Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENG-6459][ENG-6637][ENG-6638] Add Create new preprint version button #2423

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/models/preprint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ export interface PreprintLicenseRecordModel {
year: string;
}

const newVersionAllowedReviewsStates = [
ReviewsState.ACCEPTED,
ReviewsState.WITHDRAWAL_REJECTED,
ReviewsState.PENDING_WITHDRAWAL,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't know withdrawal can have pending and rejected states. I need to check BE to see if we are handling this properly.

Copy link
Collaborator

@cslzchen cslzchen Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@futa-ikeda for pre-moderation, "accepted" is correct but for post moderation, it should be "pending" or " accepted". I am not 100% sure how frontend maps backend wording.

See: https://openscience.atlassian.net/browse/ENG-6467. I think FE can probably just use the is_lateset_version without caring about the review state?

Copy link
Contributor Author

@futa-ikeda futa-ikeda Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, interesting... I see what you are saying about some of the reviews_states for pre-mod vs. post-mod lining up to be the same state (ie: for pre-mod, "reviews_state": "pending" => "is_published": false, but for post-moderation, either "reviews_state": "pending" or "accepted" => "is_published": true). I'm not sure if we can fully ignore the reviews_state flag here though, as we shouldn't be allowing a new version for "pre-moderation and rejected" and "pre-moderation and pending moderator approval", right?

Copy link
Collaborator

@cslzchen cslzchen Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, as discussed, let's rely on date_published instead of is_published. There will be a BE fix to make sure is_latest_version checks date_published instead of is_published.

];

export default class PreprintModel extends AbstractNodeModel {
@attr('fixstring') title!: string;
@attr('date') dateCreated!: Date;
Expand Down Expand Up @@ -128,6 +134,17 @@ export default class PreprintModel extends AbstractNodeModel {
.replace(/({{year}})/g, year)
.replace(/({{copyrightHolders}})/g, copyright_holders.join(', '));
}

get currentUserIsAdmin(): boolean {
return this.currentUserPermissions.includes(Permission.Admin);
}

get canCreateNewVersion(): boolean {
const hasPermission = this.currentUserIsAdmin;
const isReviewStateValid = newVersionAllowedReviewsStates.includes(this.reviewsState);
const isVersionValid = this.isLatestVersion;
return hasPermission && isReviewStateValid && isVersionValid;
}
}

declare module 'ember-data/types/registries/model' {
Expand Down
13 changes: 4 additions & 9 deletions app/preprints/detail/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ export default class PrePrintsDetailController extends Controller {
}

get editButtonLabel(): string {
const editPreprint = 'preprints.detail.project_button.edit_preprint';
const editResubmitPreprint = 'preprints.detail.project_button.edit_resubmit_preprint';
const editPreprint = 'preprints.detail.edit_preprint';
const editResubmitPreprint = 'preprints.detail.edit_resubmit_preprint';
const translation = this.model.provider.reviewsWorkflow === PreprintProviderReviewsWorkFlow.PRE_MODERATION
&& this.model.preprint.reviewsState === ReviewsState.REJECTED && this.isAdmin()
&& this.model.preprint.reviewsState === ReviewsState.REJECTED && this.model.preprint.currentUserIsAdmin
? editResubmitPreprint : editPreprint;
return this.intl.t(translation, {
documentType: this.model.provider.documentType.singular,
Expand All @@ -90,19 +90,14 @@ export default class PrePrintsDetailController extends Controller {
return this.model.preprint.title;
}

private isAdmin(): boolean {
// True if the current user has admin permissions for the node that contains the preprint
return (this.model.preprint.currentUserPermissions).includes(Permission.Admin);
}

private hasReadWriteAccess(): boolean {
// True if the current user has write permissions for the node that contains the preprint
return (this.model.preprint.currentUserPermissions.includes(Permission.Write));
}


get userIsContrib(): boolean {
if (this.isAdmin()) {
if (this.model.preprint.currentUserIsAdmin) {
return true;
} else if (this.model.contributors.length) {
const authorIds = [] as string[];
Expand Down
12 changes: 12 additions & 0 deletions app/preprints/detail/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@

</OsfLink>
{{/if}}
{{#if this.model.preprint.canCreateNewVersion}}
<OsfLink
data-test-create-new-version-button
data-analytics-name='Create new version'
local-class='btn btn-primary'
{{!-- TODO: Update when new version route is implemented --}}
@route='preprints.edit'
@models={{array this.model.provider.id this.model.preprint.id}}
>
{{t 'preprints.detail.create_new_version'}}
</OsfLink>
{{/if}}
<br>
</div>
{{/unless}}
Expand Down
107 changes: 107 additions & 0 deletions tests/acceptance/preprints/detail-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { currentRouteName } from '@ember/test-helpers';
import { ModelInstance } from 'ember-cli-mirage';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { TestContext } from 'ember-test-helpers';
import { module, skip, test } from 'qunit';

import { setupOSFApplicationTest, visit } from 'ember-osf-web/tests/helpers';
import PreprintProviderModel from 'ember-osf-web/models/preprint-provider';
import PreprintModel from 'ember-osf-web/models/preprint';
import { PreprintProviderReviewsWorkFlow, ReviewsState } from 'ember-osf-web/models/provider';
import { Permission } from 'ember-osf-web/models/osf-model';

interface PreprintDetailTestContext extends TestContext {
provider: ModelInstance<PreprintProviderModel>;
preprint: ModelInstance<PreprintModel>;
}

module('Acceptance | preprints | detail', hooks => {
setupOSFApplicationTest(hooks);
setupMirage(hooks);

hooks.beforeEach(async function(this: PreprintDetailTestContext) {
server.loadFixtures('preprint-providers');
const provider = server.schema.preprintProviders.find('osf') as ModelInstance<PreprintProviderModel>;
provider.update({
reviewsWorkflow: PreprintProviderReviewsWorkFlow.PRE_MODERATION,
assertionsEnabled: true,
});

const preprint = server.create('preprint', {
id: 'test',
provider,
currentUserPermissions: Object.values(Permission),
title: 'Test Preprint',
description: 'This is a test preprint',
});
this.provider = provider;
this.preprint = preprint;
});

test('Accepted preprint detail page', async function(this: PreprintDetailTestContext, assert) {
this.preprint.update({
reviewsState: ReviewsState.ACCEPTED,
});
await visit('/preprints/osf/test');
assert.equal(currentRouteName(), 'preprints.detail', 'Current route is preprint detail');

// Check page title
const pageTitle = document.getElementsByTagName('title')[0].innerText;
assert.equal(pageTitle, 'OSF Preprints | Test Preprint', 'Page title is correct');

// Check preprint title
assert.dom('[data-test-preprint-title]').exists('Title is displayed');
assert.dom('[data-test-preprint-title]').hasText('Test Preprint', 'Title is correct');

// Check edit and new version buttons
assert.dom('[data-test-edit-preprint-button]').exists('Edit button is displayed');
assert.dom('[data-test-edit-preprint-button]').containsText('Edit', 'Edit button text is correct');
assert.dom('[data-test-create-new-version-button]').exists('New version button is displayed');

// Check preprint authors
assert.dom('[data-test-contributor-name]').exists('Authors are displayed');

// TODO: Check author assertions

// Check preprint status banner
assert.dom('[data-test-status]').exists('Status banner is displayed');
assert.dom('[data-test-status]').containsText('accepted', 'Status is correct');
});

test('Pre-mod: Rejected preprint detail page', async function(this: PreprintDetailTestContext, assert) {
this.provider.update({
reviewsWorkflow: PreprintProviderReviewsWorkFlow.PRE_MODERATION,
});
this.preprint.update({
reviewsState: ReviewsState.REJECTED,
});
await visit('/preprints/osf/test');
assert.equal(currentRouteName(), 'preprints.detail', 'Current route is preprint detail');

// Check page title. Should be same as accepted preprint
const pageTitle = document.getElementsByTagName('title')[0].innerText;
assert.equal(pageTitle, 'OSF Preprints | Test Preprint', 'Page title is correct');

// Check preprint title. Should be same as accepted preprint
assert.dom('[data-test-preprint-title]').exists('Title is displayed');
assert.dom('[data-test-preprint-title]').hasText('Test Preprint', 'Title is correct');

// Check edit and new version buttons
assert.dom('[data-test-edit-preprint-button]').exists('Edit button is displayed');
assert.dom('[data-test-edit-preprint-button]')
.hasText('Edit and resubmit', 'Edit button text indicates resubmission');
assert.dom('[data-test-create-new-version-button]').doesNotExist('New version button is not displayed');

// Check preprint authors
assert.dom('[data-test-contributor-name]').exists('Authors are displayed');

// Check preprint status banner
assert.dom('[data-test-status]').exists('Status banner is displayed');
assert.dom('[data-test-status]').containsText('rejected', 'Status is correct');
});


skip('Withdrawn preprint detail page', async function(this: PreprintDetailTestContext, _) {
// TODO: Implement test
});
});
6 changes: 3 additions & 3 deletions translations/en-us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1437,9 +1437,9 @@ preprints:
no_doi: 'No DOI'
preprint_pending_doi_minted: 'DOIs are minted by a third party, and may take up to 24 hours to be registered.'
private_preprint_warning: 'This {documentType} is private. Contact {supportEmail} if this is in error.'
project_button:
edit_preprint: 'Edit {documentType}'
edit_resubmit_preprint: 'Edit and resubmit'
edit_preprint: 'Edit {documentType}'
edit_resubmit_preprint: 'Edit and resubmit'
create_new_version: 'Create new version'
see_less: 'See less'
see_more: 'See more'
share:
Expand Down
Loading