Repository: oppia/oppia

Issue:
[Feature Request]:GSoCM2.6 Implementing filtering for all 4 tabs in /contributor-dashboard-admin.  E2e tests for filtering.
### Is your feature request related to a problem? Please describe.

Implementing filtering for all 4 tabs in /contributor-dashboard-admin. E2e tests for filtering

Sub part of #17440. 

### Describe the solution (or solutions) you'd like

Implementing filtering for all 4 tabs in /contributor-dashboard-admin. E2e tests for filtering


### Describe alternatives you've considered and rejected

_No response_

### Additional context

_No response_


Discussion:

Resolving patch:
diff --git a/core/controllers/admin.py b/core/controllers/admin.py
--- a/core/controllers/admin.py
+++ b/core/controllers/admin.py
@@ -80,6 +80,9 @@
     )
 ])
 
+supported_languages: List[str] = [
+    lang['id'] for lang in constants.SUPPORTED_AUDIO_LANGUAGES]
+
 
 class ClassroomPageDataDict(TypedDict):
     """Dict representation of classroom page's data dictionary."""
@@ -2126,7 +2129,8 @@ class TranslationCoordinatorRoleHandler(
             },
             'language_id': {
                 'schema': {
-                    'type': 'basestring'
+                    'type': 'basestring',
+                    'choices': supported_languages
                 }
             }
         }


Test patch:
diff --git a/core/tests/webdriverio_desktop/adminTabFeatures.js b/core/tests/webdriverio_desktop/adminTabFeatures.js
--- a/core/tests/webdriverio_desktop/adminTabFeatures.js
+++ b/core/tests/webdriverio_desktop/adminTabFeatures.js
@@ -59,7 +59,7 @@ describe('Admin Page', function() {
       await users.createUser('user1@admintab.com', 'user1');
       await users.login('management@adminTab.com');
 
-      await adminPage.makeUserTranslationCoordinator('user1');
+      await adminPage.makeUserTranslationCoordinator('user1', 'English');
       await adminPage.expectUserRolesToMatch(
         'user1', ['full user', 'translation coordinator']);
     });
diff --git a/core/tests/webdriverio_desktop/contributorAdminDashboard.js b/core/tests/webdriverio_desktop/contributorAdminDashboard.js
--- a/core/tests/webdriverio_desktop/contributorAdminDashboard.js
+++ b/core/tests/webdriverio_desktop/contributorAdminDashboard.js
@@ -100,7 +100,9 @@ describe('Contributor Admin Dashboard', function() {
     await adminPage.get();
     await adminPage.addRole('management', 'release coordinator');
     await adminPage.addRole('question', 'question coordinator');
-    await adminPage.makeUserTranslationCoordinator('translation');
+    await adminPage.makeUserTranslationCoordinator('translation', 'English');
+    await adminPage.addLanguageToCoordinator('translation', 'shqip (Albanian)');
+    await adminPage.addLanguageToCoordinator('translation', 'العربية (Arabic)');
     await adminPage.addRole('question', 'translation admin');
     await users.logout();
 
@@ -111,6 +113,8 @@ describe('Contributor Admin Dashboard', function() {
     await contributorDashboardAdminPage.assignQuestionReviewer('user1');
     await contributorDashboardAdminPage.assignTranslationReviewer(
       'user1', 'shqip (Albanian)');
+    await contributorDashboardAdminPage.assignTranslationReviewer(
+      'user1', 'English');
     await users.logout();
 
     // Populating Dashboard.
@@ -276,7 +280,7 @@ describe('Contributor Admin Dashboard', function() {
     await users.logout();
   });
 
-  it('should allow user to navigate to new dashboard', async function() {
+  it('should allow question coordinator to view dashboard', async function() {
     await users.login(QUESTION_COORDINATOR_EMAIL);
     await contributorDashboardAdminPage.get();
 
@@ -289,15 +293,31 @@ describe('Contributor Admin Dashboard', function() {
     await contributorDashboardAdminPage.expectStatsRowsAreExpanded();
 
     await users.logout();
+  });
 
-    await users.login(TRANSLATION_COORDINATOR_EMAIL);
-    await contributorDashboardAdminPage.get();
+  it('should allow translation coordinator to view dashboard',
+    async function() {
+      await users.login(TRANSLATION_COORDINATOR_EMAIL);
+      await contributorDashboardAdminPage.get();
 
-    await contributorDashboardAdminPage.navigateToTranslationSubmitterTab();
-    await contributorDashboardAdminPage.expectStatsElementCountToBe(0);
-    await contributorDashboardAdminPage.navigateToTranslationReviewerTab();
-    await contributorDashboardAdminPage.expectStatsElementCountToBe(0);
+      await contributorDashboardAdminPage.navigateToTranslationSubmitterTab();
+      await contributorDashboardAdminPage.waitForLoadingMessageToDisappear();
+      await contributorDashboardAdminPage.expectNoStatsElement();
 
-    await users.logout();
-  });
+      await contributorDashboardAdminPage.switchLanguage('shqip (Albanian)');
+      await contributorDashboardAdminPage.waitForLoadingMessageToDisappear();
+      await contributorDashboardAdminPage.expectStatsElementCountToBe(2);
+      await contributorDashboardAdminPage.expectStatsRowsAreExpanded();
+
+      await contributorDashboardAdminPage.navigateToTranslationReviewerTab();
+      await contributorDashboardAdminPage.waitForLoadingMessageToDisappear();
+      await contributorDashboardAdminPage.expectStatsElementCountToBe(2);
+      await contributorDashboardAdminPage.expectStatsRowsAreExpanded();
+
+      await contributorDashboardAdminPage.switchLanguage('English');
+      await contributorDashboardAdminPage.waitForLoadingMessageToDisappear();
+      await contributorDashboardAdminPage.expectNoStatsElement(0);
+
+      await users.logout();
+    });
 });
diff --git a/core/tests/webdriverio_utils/AdminPage.js b/core/tests/webdriverio_utils/AdminPage.js
--- a/core/tests/webdriverio_utils/AdminPage.js
+++ b/core/tests/webdriverio_utils/AdminPage.js
@@ -61,6 +61,7 @@ var AdminPage = function() {
   var languageSelectorCloseButton = $(
     '.e2e-test-language-selector-close-button');
   var languageSelectorAddButton = $('.e2e-test-language-selector-add-button');
+  var editLanguageButton = $('.e2e-test-edit-language-button');
 
   // The reload functions are used for mobile testing
   // done via Browserstack. These functions may cause
@@ -218,24 +219,28 @@ var AdminPage = function() {
       removeButtonElement, 'Role removal button takes too long to appear.');
   };
 
-  this.makeUserTranslationCoordinator = async function(name) {
-    await this._editUserRole(name);
-
-    await action.click('Add new role', addNewRoleButton);
-    await action.matSelect(
-      'New role selector', roleSelector, 'translation coordinator');
-
+  this._selectLanguage = async function(language) {
     await waitFor.visibilityOf(
       languageSelectorModal,
       'Language selector modal taking too long to appear');
     await action.select(
-      'Language selector', languageSelector, 'English'
+      'Language selector', languageSelector, language
     );
     await action.click('Add language button', languageSelectorAddButton);
     await action.click('Close button', languageSelectorCloseButton);
     await waitFor.invisibilityOf(
       languageSelectorModal,
       'Language selector modal taking too long to disappear');
+  };
+
+  this.makeUserTranslationCoordinator = async function(name, language) {
+    await this._editUserRole(name);
+
+    await action.click('Add new role', addNewRoleButton);
+    await action.matSelect(
+      'New role selector', roleSelector, 'translation coordinator');
+
+    await this._selectLanguage(language);
 
     await waitFor.invisibilityOf(
       progressSpinner, 'Progress spinner is taking too long to disappear.');
@@ -247,6 +252,14 @@ var AdminPage = function() {
       removeButtonElement, 'Role removal button takes too long to appear.');
   };
 
+  this.addLanguageToCoordinator = async function(name, language) {
+    await this._editUserRole(name);
+    await action.click(
+      'Edit coordinated languages button',
+      editLanguageButton);
+    await this._selectLanguage(language);
+  };
+
   this.getUsersAsssignedToRole = async function(role) {
     await action.select('Role Drop Down', roleDropdown, 'By Role');
     await action.select('Role Value Option', roleValueOption, role);
diff --git a/core/tests/webdriverio_utils/ContributorDashboardAdminPage.js b/core/tests/webdriverio_utils/ContributorDashboardAdminPage.js
--- a/core/tests/webdriverio_utils/ContributorDashboardAdminPage.js
+++ b/core/tests/webdriverio_utils/ContributorDashboardAdminPage.js
@@ -58,6 +58,10 @@ var ContributorDashboardAdminPage = function() {
   var questionReviewerTab = $('.e2e-test-question-reviewers-tab');
   var translationSubmitterTab = $('.e2e-test-translation-submitters-tab');
   var translationReviewerTab = $('.e2e-test-translation-reviewers-tab');
+  var languageSelector = $('.e2e-test-language-selector');
+  var noDataMessage = $('.e2e-test-no-data-message');
+  var loadingMessage = $('.e2e-test-loading-message');
+  var languageDropdown = $('.e2e-test-language-selector-dropdown');
 
   this.get = async function() {
     await browser.url('/contributor-dashboard-admin');
@@ -184,6 +188,16 @@ var ContributorDashboardAdminPage = function() {
     await _assignContributionRights(username, CATEGORY_SUBMIT_QUESTION);
   };
 
+  this.switchLanguage = async function(language) {
+    await action.click('Language Selector', languageSelector);
+    await waitFor.visibilityOf(
+      languageDropdown, 'Language Dropdown not visible');
+    var selectorOption = languageSelector.$(
+      `.e2e-test-language-selector-option=${language}`);
+    await action.click(`${language} option selector`, selectorOption);
+    await action.click('Language Selector', languageSelector);
+  };
+
   this.expectUserToBeTranslationReviewer = async function(
       username, languageDescription) {
     var contributionRights = await _getUserContributionRightsElement(
@@ -225,11 +239,20 @@ var ContributorDashboardAdminPage = function() {
   };
 
   this.expectStatsElementCountToBe = async function(elementsCount) {
+    await waitFor.invisibilityOf(
+      loadingMessage, 'Loading message did not disappear');
     await waitFor.visibilityOf(statsTable, 'stats table is not visible');
     var statsListItems = await statsListItemsSelector();
     expect(statsListItems.length).toBe(elementsCount);
   };
 
+  this.expectNoStatsElement = async function() {
+    await waitFor.invisibilityOf(
+      loadingMessage, 'Loading message did not disappear');
+    await waitFor.visibilityOf(
+      noDataMessage, 'No data message is not visible');
+  };
+
   this.expectStatsRowsAreExpanded = async function() {
     await waitFor.visibilityOf(statsTable, 'Stats table was not visible');
     var statsListItems = await statsListItemsSelector();
@@ -238,6 +261,11 @@ var ContributorDashboardAdminPage = function() {
     await action.click('Stats row', statsListItems[0]);
     await waitFor.invisibilityOf(expandedRow, 'Expanded row still visible');
   };
+
+  this.waitForLoadingMessageToDisappear = async function() {
+    await waitFor.invisibilityOf(
+      loadingMessage, 'Loading message did not disappear');
+  };
 };
 
 exports.ContributorDashboardAdminPage = ContributorDashboardAdminPage;