diff --git a/cypress/e2e/add-forge-now-request-create.cy.js b/cypress/e2e/add-forge-now-request-create.cy.js index 763e463f..47c8f6ed 100644 --- a/cypress/e2e/add-forge-now-request-create.cy.js +++ b/cypress/e2e/add-forge-now-request-create.cy.js @@ -1,258 +1,264 @@ /** * Copyright (C) 2022 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ function populateForm(type, url, contact, email, consent, comment) { cy.get('#swh-input-forge-type').select(type); cy.get('#swh-input-forge-url').clear().type(url); cy.get('#swh-input-forge-contact-name').clear().type(contact); cy.get('#swh-input-forge-contact-email').clear().type(email); if (comment) { cy.get('#swh-input-forge-comment').clear().type(comment); } cy.get('#swh-input-consent-check').click({force: consent === 'on'}); } describe('Browse requests list tests', function() { beforeEach(function() { this.addForgeNowUrl = this.Urls.forge_add_create(); this.listAddForgeRequestsUrl = this.Urls.add_forge_request_list_datatables(); }); it('should not show user requests filter checkbox for anonymous users', function() { cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#swh-add-forge-user-filter').should('not.exist'); }); it('should show user requests filter checkbox for authenticated users', function() { cy.userLogin(); cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#swh-add-forge-user-filter').should('exist').should('be.checked'); }); it('should only display user requests when filter is activated', function() { // Clean up previous state cy.task('db:add_forge_now:delete'); // 'user2' logs in and create requests cy.user2Login(); cy.visit(this.addForgeNowUrl); // create requests for the user 'user' populateForm('gitlab', 'gitlab.org', 'admin', 'admin@example.org', 'on', ''); cy.get('#requestCreateForm').submit(); // user requests filter checkbox should be in the DOM cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#swh-add-forge-user-filter').should('exist').should('be.checked'); // check unfiltered user requests cy.get('tbody tr').then(rows => { expect(rows.length).to.eq(1); }); // user1 logout cy.contains('a', 'logout').click(); // user logs in cy.userLogin(); cy.visit(this.addForgeNowUrl); populateForm('gitea', 'gitea.org', 'admin', 'admin@example.org', 'on', ''); cy.get('#requestCreateForm').submit(); populateForm('cgit', 'cgit.org', 'admin', 'admin@example.org', 'on', ''); cy.get('#requestCreateForm').submit(); // user requests filter checkbox should be in the DOM cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#swh-add-forge-user-filter').should('exist').should('be.checked'); // check unfiltered user requests cy.get('tbody tr').then(rows => { expect(rows.length).to.eq(2); }); cy.get('#swh-add-forge-user-filter') .uncheck({force: true}); // Users now sees everything cy.get('tbody tr').then(rows => { expect(rows.length).to.eq(2 + 1); }); }); }); describe('Test add-forge-request creation', function() { beforeEach(function() { this.addForgeNowUrl = this.Urls.forge_add_create(); }); it('should show all the tabs for every user', function() { cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-tab') .should('have.class', 'nav-link'); cy.get('#swh-add-forge-requests-list-tab') .should('have.class', 'nav-link'); cy.get('#swh-add-forge-requests-help-tab') .should('have.class', 'nav-link'); }); it('should show create forge tab by default', function() { cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-tab') .should('have.class', 'active'); cy.get('#swh-add-forge-requests-list-tab') .should('not.have.class', 'active'); }); it('should show login link for anonymous user', function() { cy.visit(this.addForgeNowUrl); cy.get('#loginLink') .should('be.visible') .should('contain', 'log in'); }); it('should bring back after login', function() { cy.visit(this.addForgeNowUrl); cy.get('#loginLink') .should('have.attr', 'href') .and('include', `${this.Urls.login()}?next=${this.Urls.forge_add_create()}`); }); it('should change tabs on click', function() { cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#swh-add-forge-tab') .should('not.have.class', 'active'); cy.get('#swh-add-forge-requests-list-tab') .should('have.class', 'active'); cy.get('#swh-add-forge-requests-help-tab') .should('not.have.class', 'active'); cy.url() .should('include', `${this.Urls.forge_add_list()}`); + cy.get('.swh-add-forge-now-item') + .should('have.class', 'active'); cy.get('#swh-add-forge-requests-help-tab').click(); cy.get('#swh-add-forge-tab') .should('not.have.class', 'active'); cy.get('#swh-add-forge-requests-list-tab') .should('not.have.class', 'active'); cy.get('#swh-add-forge-requests-help-tab') .should('have.class', 'active'); cy.url() .should('include', `${this.Urls.forge_add_help()}`); + cy.get('.swh-add-forge-now-item') + .should('have.class', 'active'); cy.get('#swh-add-forge-tab').click(); cy.get('#swh-add-forge-tab') .should('have.class', 'active'); cy.get('#swh-add-forge-requests-list-tab') .should('not.have.class', 'active'); cy.get('#swh-add-forge-requests-help-tab') .should('not.have.class', 'active'); cy.url() .should('include', `${this.Urls.forge_add_create()}`); + cy.get('.swh-add-forge-now-item') + .should('have.class', 'active'); }); it('should show create form elements to authenticated user', function() { cy.userLogin(); cy.visit(this.addForgeNowUrl); cy.get('#swh-input-forge-type') .should('be.visible'); cy.get('#swh-input-forge-url') .should('be.visible'); cy.get('#swh-input-forge-contact-name') .should('be.visible'); cy.get('#swh-input-consent-check') .should('be.visible'); cy.get('#swh-input-forge-comment') .should('be.visible'); cy.get('#swh-input-form-submit') .should('be.visible'); }); it('should show browse requests table for every user', function() { // testing only for anonymous cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#add-forge-request-browse') .should('be.visible'); cy.get('#loginLink') .should('not.exist'); }); it('should update browse list on successful submission', function() { cy.userLogin(); cy.visit(this.addForgeNowUrl); populateForm('bitbucket', 'gitlab.com', 'test', 'test@example.com', 'on', 'test comment'); cy.get('#requestCreateForm').submit(); cy.visit(this.addForgeNowUrl); cy.get('#swh-add-forge-requests-list-tab').click(); cy.get('#add-forge-request-browse') .should('be.visible') .should('contain', 'gitlab.com'); cy.get('#add-forge-request-browse') .should('be.visible') .should('contain', 'Pending'); }); it('should show error message on conflict', function() { cy.userLogin(); cy.visit(this.addForgeNowUrl); populateForm('bitbucket', 'gitlab.com', 'test', 'test@example.com', 'on', 'test comment'); cy.get('#requestCreateForm').submit(); cy.get('#requestCreateForm').submit(); // Submitting the same data again cy.get('#userMessage') .should('have.class', 'badge-danger') .should('contain', 'already exists'); }); it('should show error message', function() { cy.userLogin(); cy.intercept('POST', `${this.Urls.api_1_add_forge_request_create()}**`, { body: { 'exception': 'BadInputExc', 'reason': '{"add-forge-comment": ["This field is required"]}' }, statusCode: 400 }).as('errorRequest'); cy.visit(this.addForgeNowUrl); populateForm( 'bitbucket', 'gitlab.com', 'test', 'test@example.com', 'off', 'comment' ); cy.get('#requestCreateForm').submit(); cy.wait('@errorRequest').then((xhr) => { cy.get('#userMessage') .should('have.class', 'badge-danger') .should('contain', 'field is required'); }); }); }); diff --git a/cypress/e2e/add-forge-now-request-dashboard.cy.js b/cypress/e2e/add-forge-now-request-dashboard.cy.js index 4c766a2e..e2e8e859 100644 --- a/cypress/e2e/add-forge-now-request-dashboard.cy.js +++ b/cypress/e2e/add-forge-now-request-dashboard.cy.js @@ -1,308 +1,310 @@ /** * Copyright (C) 2022 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ let requestId; let requestForgeDomain; let requestInboundEmailAddress; const requestData = { forge_type: 'bitbucket', forge_url: 'test.example.com', forge_contact_email: 'test@example.com', forge_contact_name: 'test user', submitter_forward_username: true, forge_contact_comment: 'test comment' }; function createDummyRequest(urls) { cy.task('db:add_forge_now:delete'); cy.userLogin(); return cy.getCookie('csrftoken').its('value').then((token) => { cy.request({ method: 'POST', url: urls.api_1_add_forge_request_create(), body: requestData, headers: { 'X-CSRFToken': token } }).then((response) => { // setting requestId and forgeDomain from response requestId = response.body.id; requestForgeDomain = response.body.forge_domain; requestInboundEmailAddress = response.body.inbound_email_address; // logout the user cy.visit(urls.swh_web_homepage()); cy.contains('a', 'logout').click(); }); }); } function genEmailSrc() { return `Message-ID: Date: Tue, 19 Apr 2022 14:00:56 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0 To: ${requestData.forge_contact_email} Cc: ${requestInboundEmailAddress} Reply-To: ${requestInboundEmailAddress} Subject: Software Heritage archival request for test.example.com Content-Language: en-US From: Test Admin Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Dear forge administrator, The mission of Software Heritage is to collect, preserve and share all the publicly available source code (see https://www.softwareheritage.org for more information). We just received a request to add the forge hosted at https://test.example.com to the list of software origins that are archived, and it is our understanding that you are the contact person for this forge. In order to archive the forge contents, we will have to periodically pull the public repositories it contains and clone them into the Software Heritage archive. Would you be so kind as to reply to this message to acknowledge the reception of this email and let us know if there are any special steps we should take in order to properly archive the public repositories hosted on your infrastructure? Thank you in advance for your help. Kind regards, The Software Heritage team `; } describe('Test add forge now request dashboard load', function() { before(function() { // Create an add-forge-request object in the DB createDummyRequest(this.Urls); }); beforeEach(function() { const url = this.Urls.add_forge_now_request_dashboard(requestId); // request dashboard require admin permissions to view cy.adminLogin(); cy.intercept(`${this.Urls.api_1_add_forge_request_get(requestId)}**`).as('forgeRequestGet'); cy.visit(url); + cy.get('.swh-add-forge-now-moderation-item') + .should('have.class', 'active'); }); it('should load add forge request details', function() { cy.wait('@forgeRequestGet'); cy.get('#requestStatus') .should('contain', 'Pending'); cy.get('#requestType') .should('contain', 'bitbucket'); cy.get('#requestURL') .should('contain', 'test.example.com'); cy.get('#requestContactEmail') .should('contain', 'test@example.com'); cy.get('#requestContactName') .should('contain', 'test user'); cy.get('#requestContactEmail') .should('contain', 'test@example.com'); cy.get('#requestContactConsent') .should('contain', 'true'); cy.get('#submitterMessage') .should('contain', 'test comment'); }); it('should show send message link', function() { cy.wait('@forgeRequestGet'); cy.get('#contactForgeAdmin') .should('have.attr', 'emailto') .and('include', 'test@example.com'); cy.get('#contactForgeAdmin') .should('have.attr', 'emailsubject') .and('include', `Software Heritage archival request for ${requestForgeDomain}`); }); it('should not show any error message', function() { cy.wait('@forgeRequestGet'); cy.get('#fetchError') .should('have.class', 'd-none'); cy.get('#requestDetails') .should('not.have.class', 'd-none'); }); it('should show error message for an api error', function() { // requesting with a non existing request ID const invalidRequestId = requestId + 10; const url = this.Urls.add_forge_now_request_dashboard(invalidRequestId); cy.intercept(`${this.Urls.api_1_add_forge_request_get(invalidRequestId)}**`, {statusCode: 400}).as('forgeAddInvalidRequest'); cy.visit(url); cy.wait('@forgeAddInvalidRequest'); cy.get('#fetchError') .should('not.have.class', 'd-none'); cy.get('#requestDetails') .should('have.class', 'd-none'); }); it('should load add forge request history', function() { cy.wait('@forgeRequestGet'); cy.get('#requestHistory') .children() .should('have.length', 1); cy.get('#requestHistory') .children() .should('contain', 'New status: Pending'); cy.get('#requestHistory') .should('contain', 'From user (SUBMITTER)'); }); it('should load possible next status', function() { cy.wait('@forgeRequestGet'); // 3 possible next status and the comment option cy.get('#decisionOptions') .children() .should('have.length', 4); }); }); function populateAndSubmitForm() { cy.get('#decisionOptions').select('WAITING_FOR_FEEDBACK'); cy.get('#updateComment').type('This is an update comment'); cy.get('#updateRequestForm').submit(); } describe('Test add forge now request update', function() { beforeEach(function() { createDummyRequest(this.Urls).then(() => { this.url = this.Urls.add_forge_now_request_dashboard(requestId); cy.adminLogin(); // intercept GET API on page load cy.intercept(`${this.Urls.api_1_add_forge_request_get(requestId)}**`).as('forgeRequestGet'); // intercept update POST API cy.intercept('POST', `${this.Urls.api_1_add_forge_request_update(requestId)}**`).as('forgeRequestUpdate'); cy.visit(this.url).then(() => { cy.wait('@forgeRequestGet'); }); }); }); it('should submit correct details', function() { populateAndSubmitForm(); // Making sure posting the right data cy.wait('@forgeRequestUpdate').its('request.body') .should('include', 'new_status') .should('include', 'text') .should('include', 'WAITING_FOR_FEEDBACK'); }); it('should show success message', function() { populateAndSubmitForm(); // Making sure showing the success message cy.wait('@forgeRequestUpdate'); cy.get('#userMessage') .should('contain', 'The request status has been updated') .should('not.have.class', 'badge-danger') .should('have.class', 'badge-success'); }); it('should update the dashboard after submit', function() { populateAndSubmitForm(); // Making sure the UI is updated after the submit cy.wait('@forgeRequestGet'); cy.get('#requestStatus') .should('contain', 'Waiting for feedback'); cy.get('#requestHistory') .children() .should('have.length', 2); cy.get('#requestHistory') .children() .should('contain', 'New status: Waiting for feedback'); cy.get('#requestHistory') .children() .should('contain', 'This is an update comment'); cy.get('#requestHistory') .children() .should('contain', 'Status changed to: Waiting for feedback'); cy.get('#decisionOptions') .children() .should('have.length', 2); }); it('should update the dashboard after receiving email', function() { const emailSrc = genEmailSrc(); cy.task('processAddForgeNowInboundEmail', emailSrc); // Refresh page and wait for the async request to complete cy.visit(this.url); cy.wait('@forgeRequestGet'); cy.get('#requestHistory') .children() .should('have.length', 2); cy.get('#historyItem1') .click() .should('contain', 'New status: Waiting for feedback'); cy.get('#historyItemBody1') .find('a') .should('contain', 'Open original message in email client') .should('have.prop', 'href').and('contain', '/message-source/').then(function(href) { cy.request(href).then((response) => { expect(response.headers['content-type']) .to.equal('text/email'); expect(response.headers['content-disposition']) .to.match(/filename="add-forge-now-test.example.com-message\d+.eml"/); expect(response.body) .to.equal(emailSrc); }); }); }); it('should show an error on API failure', function() { cy.intercept('POST', `${this.Urls.api_1_add_forge_request_update(requestId)}**`, {forceNetworkError: true}) .as('updateFailedRequest'); cy.get('#updateComment').type('This is an update comment'); cy.get('#updateRequestForm').submit(); cy.wait('@updateFailedRequest'); cy.get('#userMessage') .should('contain', 'Sorry; Updating the request failed') .should('have.class', 'badge-danger') .should('not.have.class', 'badge-success'); }); }); diff --git a/cypress/e2e/add-forge-now-requests-moderation.cy.js b/cypress/e2e/add-forge-now-requests-moderation.cy.js index 5eeec3d0..bcc2fa17 100644 --- a/cypress/e2e/add-forge-now-requests-moderation.cy.js +++ b/cypress/e2e/add-forge-now-requests-moderation.cy.js @@ -1,122 +1,125 @@ /** * Copyright (C) 2022 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ const defaultRedirect = '/admin/login/'; let addForgeModerationUrl; let listAddForgeRequestsUrl; function logout() { cy.contains('a', 'logout') .click(); } describe('Test "Add Forge Now" moderation Login/logout', function() { before(function() { addForgeModerationUrl = this.Urls.add_forge_now_requests_moderation(); }); it('should redirect to default page', function() { cy.visit(addForgeModerationUrl) .get('input[name="username"]') .type('admin') .get('input[name="password"]') .type('admin') .get('.container form') .submit(); cy.location('pathname') .should('be.equal', addForgeModerationUrl); }); it('should redirect to correct page after login', function() { cy.visit(addForgeModerationUrl) .location('pathname') .should('be.equal', defaultRedirect); cy.adminLogin(); cy.visit(addForgeModerationUrl) .location('pathname') .should('be.equal', addForgeModerationUrl); logout(); }); it('should not display moderation link in sidebar when anonymous', function() { cy.visit(addForgeModerationUrl); cy.get(`.sidebar a[href="${addForgeModerationUrl}"]`) .should('not.exist'); }); it('should not display moderation link when connected as unprivileged user', function() { cy.userLogin(); cy.visit(addForgeModerationUrl); cy.get(`.sidebar a[href="${addForgeModerationUrl}"]`) .should('not.exist'); }); it('should display moderation link in sidebar when connected as privileged user', function() { cy.addForgeModeratorLogin(); cy.visit(addForgeModerationUrl); cy.get(`.sidebar a[href="${addForgeModerationUrl}"]`) .should('exist'); }); it('should display moderation link in sidebar when connected as staff member', function() { cy.adminLogin(); cy.visit(addForgeModerationUrl); cy.get(`.sidebar a[href="${addForgeModerationUrl}"]`) .should('exist'); }); }); describe('Test "Add Forge Now" moderation listing', function() { before(function() { addForgeModerationUrl = this.Urls.add_forge_now_requests_moderation(); listAddForgeRequestsUrl = this.Urls.add_forge_request_list_datatables(); }); it('should list add-forge-now requests', function() { cy.intercept(`${listAddForgeRequestsUrl}**`, {fixture: 'add-forge-now-requests'}).as('listRequests'); let expectedRequests; cy.readFile('cypress/fixtures/add-forge-now-requests.json').then((result) => { expectedRequests = result['data']; }); cy.addForgeModeratorLogin(); cy.visit(addForgeModerationUrl); + cy.get('.swh-add-forge-now-moderation-item') + .should('have.class', 'active'); + cy.wait('@listRequests').then((xhr) => { cy.log('response:', xhr.response); cy.log(xhr.response.body); const requests = xhr.response.body.data; cy.log('Requests: ', requests); expect(requests.length).to.equal(expectedRequests.length); cy.get('#swh-add-forge-now-moderation-list').find('tbody > tr').as('rows'); // only 2 entries cy.get('@rows').each((row, idx, collection) => { const request = requests[idx]; const expectedRequest = expectedRequests[idx]; assert.isNotNull(request); assert.isNotNull(expectedRequest); expect(request.id).to.be.equal(expectedRequest['id']); expect(request.status).to.be.equal(expectedRequest['status']); expect(request.submission_date).to.be.equal(expectedRequest['submission_date']); expect(request.forge_type).to.be.equal(expectedRequest['forge_type']); expect(request.forge_url).to.be.equal(expectedRequest['forge_url']); }); }); }); }); diff --git a/cypress/e2e/mailmap.cy.js b/cypress/e2e/mailmap.cy.js index 10c350ab..4439a7d8 100644 --- a/cypress/e2e/mailmap.cy.js +++ b/cypress/e2e/mailmap.cy.js @@ -1,226 +1,228 @@ /** * Copyright (C) 2022 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ const $ = Cypress.$; function fillFormAndSubmitMailmap(fromEmail, displayName, activated) { if (fromEmail) { cy.get('#swh-mailmap-from-email') .clear() .type(fromEmail); } if (displayName) { cy.get('#swh-mailmap-display-name') .clear() .type(displayName); } if (activated) { cy.get('#swh-mailmap-display-name-activated') .check({force: true}); } else { cy.get('#swh-mailmap-display-name-activated') .uncheck({force: true}); } cy.get('#swh-mailmap-form-submit') .click(); } function addNewMailmap(fromEmail, displayName, activated) { cy.get('#swh-add-new-mailmap') .click(); fillFormAndSubmitMailmap(fromEmail, displayName, activated); } function updateMailmap(fromEmail, displayName, activated) { cy.contains('Edit') .click(); fillFormAndSubmitMailmap(fromEmail, displayName, activated); } function checkMailmapRow(fromEmail, displayName, activated, processed = false, row = 1, nbRows = 1) { cy.get('tbody tr').then(rows => { assert.equal(rows.length, 1); const cells = rows[0].cells; assert.equal($(cells[0]).text(), fromEmail); assert.include($(cells[1]).html(), 'mdi-check-bold'); assert.equal($(cells[2]).text(), displayName); assert.include($(cells[3]).html(), activated ? 'mdi-check-bold' : 'mdi-close-thick'); assert.notEqual($(cells[4]).text(), ''); assert.include($(cells[5]).html(), processed ? 'mdi-check-bold' : 'mdi-close-thick'); }); } describe('Test mailmap administration', function() { before(function() { this.url = this.Urls.admin_mailmap(); }); beforeEach(function() { cy.task('db:user_mailmap:delete'); cy.intercept('POST', this.Urls.profile_mailmap_add()) .as('mailmapAdd'); cy.intercept('POST', this.Urls.profile_mailmap_update()) .as('mailmapUpdate'); cy.intercept(`${this.Urls.profile_mailmap_list_datatables()}**`) .as('mailmapList'); }); it('should not display mailmap admin link in sidebar when anonymous', function() { cy.visit(this.url); cy.get('.swh-mailmap-admin-item') .should('not.exist'); }); it('should not display mailmap admin link when connected as unprivileged user', function() { cy.userLogin(); cy.visit(this.url); cy.get('.swh-mailmap-admin-item') .should('not.exist'); }); it('should display mailmap admin link in sidebar when connected as privileged user', function() { cy.mailmapAdminLogin(); cy.visit(this.url); cy.get('.swh-mailmap-admin-item') - .should('exist'); + .should('exist') + .should('have.class', 'active'); + }); it('should not create a new mailmap when input data are empty', function() { cy.mailmapAdminLogin(); cy.visit(this.url); addNewMailmap('', '', true); cy.get('#swh-mailmap-form :invalid').should('exist'); cy.get('#swh-mailmap-form') .should('be.visible'); }); it('should not create a new mailmap when from email is invalid', function() { cy.mailmapAdminLogin(); cy.visit(this.url); addNewMailmap('invalid_email', 'display name', true); cy.get('#swh-mailmap-form :invalid').should('exist'); cy.get('#swh-mailmap-form') .should('be.visible'); }); it('should create a new mailmap when input data are valid', function() { cy.mailmapAdminLogin(); cy.visit(this.url); const fromEmail = 'user@example.org'; const displayName = 'New user display name'; addNewMailmap(fromEmail, displayName, true); cy.wait('@mailmapAdd'); cy.get('#swh-mailmap-form :invalid').should('not.exist'); // ensure table redraw before next check cy.contains(fromEmail); cy.get('#swh-mailmap-form') .should('not.be.visible'); checkMailmapRow(fromEmail, displayName, true); }); it('should not create a new mailmap for an email already mapped', function() { cy.mailmapAdminLogin(); cy.visit(this.url); const fromEmail = 'user@example.org'; const displayName = 'New user display name'; addNewMailmap(fromEmail, displayName, true); cy.wait('@mailmapAdd'); addNewMailmap(fromEmail, displayName, true); cy.wait('@mailmapAdd'); cy.get('#swh-mailmap-form') .should('not.be.visible'); cy.contains('Error') .should('be.visible'); checkMailmapRow(fromEmail, displayName, true); }); it('should update a mailmap', function() { cy.mailmapAdminLogin(); cy.visit(this.url); const fromEmail = 'user@example.org'; const displayName = 'New display name'; addNewMailmap(fromEmail, displayName, false); cy.wait('@mailmapAdd'); cy.get('#swh-mailmap-form :invalid').should('not.exist'); // ensure table redraw before next check cy.contains(fromEmail); cy.get('#swh-mailmap-form') .should('not.be.visible'); checkMailmapRow(fromEmail, displayName, false); const newDisplayName = 'Updated display name'; updateMailmap('', newDisplayName, true); cy.wait('@mailmapUpdate'); cy.get('#swh-mailmap-form :invalid').should('not.exist'); // ensure table redraw before next check cy.contains(fromEmail); cy.get('#swh-mailmap-form') .should('not.be.visible'); checkMailmapRow(fromEmail, newDisplayName, true); }); it('should indicate when a mailmap has been processed', function() { cy.mailmapAdminLogin(); cy.visit(this.url); const fromEmail = 'user@example.org'; const displayName = 'New user display name'; addNewMailmap(fromEmail, displayName, true); cy.wait('@mailmapAdd'); // ensure table redraw before next check cy.contains(fromEmail); checkMailmapRow(fromEmail, displayName, true, false); cy.task('db:user_mailmap:mark_processed'); cy.visit(this.url); checkMailmapRow(fromEmail, displayName, true, true); }); }); diff --git a/swh/web/templates/add_forge_now/common.html b/swh/web/templates/add_forge_now/common.html index 7569acdb..24d34466 100644 --- a/swh/web/templates/add_forge_now/common.html +++ b/swh/web/templates/add_forge_now/common.html @@ -1,71 +1,72 @@ {% extends "../layout.html" %} {% comment %} Copyright (C) 2022 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load render_bundle from webpack_loader %} {% load static %} {% block header %} {% render_bundle 'add_forge' %} {% endblock %} {% block title %} Add forge now – Software Heritage archive {% endblock %} {% block navbar-content %}

Request the addition of a forge into the archive

{% endblock %} {% block content %}

“Add forge now” provides a service for Software Heritage users to save a complete forge in the Software Heritage archive by requesting the addition of the forge URL into the list of regularly visited forges.

{% if not user.is_authenticated %}

You can submit an “Add forge now” request only when you are authenticated, please login to submit the request.

{% endif %}
{% block tab_content %} {% endblock %}
{% endblock %} diff --git a/swh/web/templates/add_forge_now/request-dashboard.html b/swh/web/templates/add_forge_now/request-dashboard.html index 8fc0f7fc..0f9e14c9 100644 --- a/swh/web/templates/add_forge_now/request-dashboard.html +++ b/swh/web/templates/add_forge_now/request-dashboard.html @@ -1,120 +1,121 @@ {% extends "../layout.html" %} {% comment %} Copyright (C) 2022 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load render_bundle from webpack_loader %} {% load static %} {% block header %} {% render_bundle 'add_forge' %} {% endblock %} {% block title %}{{heading}} – Software Heritage archive{% endblock %} {% block navbar-content %}

Add forge now request dashboard

{% endblock %} {% block content %}

Error fetching information about the request

{% csrf_token %}
Enter a comment related to your decision.

Request status

Forge type

Forge URL

Contact name

Consent to use name

Contact email

Message


{% endblock %} diff --git a/swh/web/templates/add_forge_now/requests-moderation.html b/swh/web/templates/add_forge_now/requests-moderation.html index b15fde07..6d3010d1 100644 --- a/swh/web/templates/add_forge_now/requests-moderation.html +++ b/swh/web/templates/add_forge_now/requests-moderation.html @@ -1,47 +1,48 @@ {% extends "../layout.html" %} {% comment %} Copyright (C) 2022 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load render_bundle from webpack_loader %} {% load static %} {% block header %} {% render_bundle 'add_forge' %} {% endblock %} {% block title %}{{ heading }} – Software Heritage archive{% endblock %} {% block navbar-content %}

Add forge now moderation

{% endblock %} {% block content %}
ID Submission date Forge type Forge URL Moderator Name Last Modified Date Status

{% endblock %} diff --git a/swh/web/templates/admin/mailmap.html b/swh/web/templates/admin/mailmap.html index d45f9dea..3ac87e2e 100644 --- a/swh/web/templates/admin/mailmap.html +++ b/swh/web/templates/admin/mailmap.html @@ -1,53 +1,54 @@ {% extends "layout.html" %} {% comment %} Copyright (C) 2022 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load swh_templatetags %} {% load render_bundle from webpack_loader %} {% block header %} {{ block.super }} {% render_bundle 'admin' %} {% endblock %} {% block title %} Mailmap administration – Software Heritage archive {% endblock %} {% block navbar-content %}

Mailmap administration

{% endblock %} {% block content %}

This interface enables to manage author display names in the archive based on their emails.

Email Verified Display name Activated Last update Effective

{% endblock content %} diff --git a/swh/web/templates/layout.html b/swh/web/templates/layout.html index a4a47961..19cfb567 100644 --- a/swh/web/templates/layout.html +++ b/swh/web/templates/layout.html @@ -1,313 +1,313 @@ {% comment %} Copyright (C) 2015-2022 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load js_reverse %} {% load static %} {% load render_bundle from webpack_loader %} {% load swh_templatetags %} {% block title %}{% endblock %} {% render_bundle 'vendors' %} {% render_bundle 'webapp' %} {% render_bundle 'guided_tour' %} {{ request.user.is_authenticated|json_script:"swh_user_logged_in" }} {% include "includes/favicon.html" %} {% block header %}{% endblock %} {% if swh_web_prod %} {% endif %}
{% include "misc/hiring-banner.html" %}
{% if swh_web_staging %}
Staging
v{{ swh_web_version }}
{% elif swh_web_dev %}
Development
v{{ swh_web_version|split:"+"|first }}
{% endif %} {% block content %}{% endblock %}
{% include "includes/global-modals.html" %}
back to top