• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CenterForOpenScience / ember-osf-web / 12757530942

13 Jan 2025 10:47PM UTC coverage: 68.206%. First build
12757530942

Pull #2468

github

web-flow
Merge c9d745a39 into 51f651b65
Pull Request #2468: [ENG-6461] [ENG-6462] Move withdraw button

2960 of 4721 branches covered (62.7%)

Branch coverage included in aggregate %.

9 of 27 new or added lines in 3 files covered. (33.33%)

7425 of 10505 relevant lines covered (70.68%)

202.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.84
/app/preprints/detail/route.ts
1
import Store from '@ember-data/store';
2
import Route from '@ember/routing/route';
3
import RouterService from '@ember/routing/router-service';
4
import { inject as service } from '@ember/service';
5
import { waitFor } from '@ember/test-waiters';
6
import { taskFor } from 'ember-concurrency-ts';
7
import Intl from 'ember-intl/services/intl';
8
import { all, restartableTask } from 'ember-concurrency';
9
import moment from 'moment-timezone';
10

11
import config from 'ember-osf-web/config/environment';
12
import CurrentUser from 'ember-osf-web/services/current-user';
13
import Identifier from 'ember-osf-web/models/identifier';
14
import LicenseModel from 'ember-osf-web/models/license';
15
import { ReviewsState } from 'ember-osf-web/models/provider';
16
import { SparseModel } from 'ember-osf-web/utils/sparse-fieldsets';
17
import MetaTags, { HeadTagDef } from 'ember-osf-web/services/meta-tags';
18
import Ready from 'ember-osf-web/services/ready';
19
import Theme from 'ember-osf-web/services/theme';
20
import captureException from 'ember-osf-web/utils/capture-exception';
21
import { notFoundURL } from 'ember-osf-web/utils/clean-url';
22
import pathJoin from 'ember-osf-web/utils/path-join';
23

24
import PrePrintsDetailController from './controller';
25

26

27
/**
28
 * @module ember-preprints
29
 * @submodule routes
30
 */
31

32
/**
33
 * @class Content Route Handler
34
 */
35

36

37
/**
38
 * Loads all disciplines and preprint providers to the index page
39
 * @class Index Route Handler
40
 */
41
export default class PreprintsDetail extends Route {
42
    @service store!: Store;
43
    @service theme!: Theme;
44
    @service router!: RouterService;
45
    @service currentUser!: CurrentUser;
46
    @service metaTags!: MetaTags;
47
    @service ready!: Ready;
48
    @service intl!: Intl;
49

50
    headTags?: HeadTagDef[];
51

52
    async model(params: { guid : string }) {
53
        try {
6✔
54
            const guid = params.guid;
6✔
55

56
            const preprint = await this.store.findRecord('preprint', guid, {
6✔
57
                adapterOptions: {
58
                    query: {
59
                        'metrics[views]': 'total',
60
                        'metrics[downloads]': 'total',
61
                    },
62
                },
63
            });
64

65
            const provider = await preprint?.get('provider');
6✔
66

67
            this.theme.set('providerType', 'preprint');
6✔
68
            this.theme.set('id', provider.id);
6✔
69

70
            let primaryFile;
71

72
            if (!preprint.isWithdrawn) {
6✔
73
                primaryFile = await preprint?.get('primaryFile');
4✔
74
                primaryFile.versions = await primaryFile?.versions;
4✔
75
            }
76

77
            const contributors = await preprint?.queryHasMany('contributors');
6✔
78

79
            const license = await preprint?.get('license');
6✔
80

81
            const subjects = await preprint?.queryHasMany('subjects');
6✔
82
            const versions = await preprint?.queryHasMany('versions');
6✔
83

84
            const preprintWithdrawableState = [ReviewsState.ACCEPTED, ReviewsState.PENDING]
6✔
85
                .includes(preprint.reviewsState);
86
            let isWithdrawalRejected = false;
6✔
87
            let hasPendingWithdrawal = false;
6✔
88
            if (preprintWithdrawableState) {
6✔
89
                const withdrawalRequests = await preprint?.queryHasMany('requests');
3✔
90
                const latestWithdrawalRequest = withdrawalRequests.firstObject;
3✔
91
                if (latestWithdrawalRequest) {
3!
NEW
92
                    hasPendingWithdrawal = latestWithdrawalRequest.machineState === 'pending';
×
NEW
93
                    const requestActions = await withdrawalRequests.firstObject?.queryHasMany('actions', {
×
94
                        sort: '-modified',
95
                    });
NEW
96
                    const latestRequestAction = requestActions.firstObject;
×
97
                    // @ts-ignore: ActionTrigger is never
NEW
98
                    if (latestRequestAction && latestRequestAction.actionTrigger === 'reject') {
×
NEW
99
                        isWithdrawalRejected = true;
×
100
                    }
101
                }
102
            }
103
            const canDisplayWithdrawalButton = preprint.currentUserIsAdmin && preprintWithdrawableState
6✔
104
                && !isWithdrawalRejected && !hasPendingWithdrawal;
105

106
            return {
6✔
107
                preprint,
108
                brand: provider.brand.content,
109
                contributors,
110
                provider,
111
                primaryFile,
112
                license,
113
                subjects,
114
                versions,
115
                canDisplayWithdrawalButton,
116
            };
117

118
        } catch (error) {
119
            captureException(error);
×
120
            this.router.transitionTo('not-found', notFoundURL(window.location.pathname));
×
121
            return null;
×
122
        }
123
    }
124

125
    @restartableTask({ cancelOn: 'deactivate' })
126
    @waitFor
127
    async setHeadTags(model: any) {
128
        const blocker = this.ready.getBlocker();
6✔
129
        const {preprint} = await model;
6✔
130

131
        if (preprint) {
6!
132
            const [
133
                contributors = [],
×
134
                license = null,
×
135
                identifiers = [],
×
136
                provider = null,
×
137
            ] = await all([
6✔
138
                preprint.sparseLoadAll(
139
                    'bibliographicContributors',
140
                    { contributor: ['users', 'index'], user: ['fullName'] },
141
                ),
142
                preprint.license,
143
                preprint.identifiers,
144
                preprint.provider,
145
            ]);
146

147
            const doi = (identifiers as Identifier[]).find(identifier => identifier.category === 'doi');
6✔
148
            const image = 'engines-dist/registries/assets/img/osf-sharing.png';
6✔
149

150
            const preprintTitle = preprint.isWithdrawn ?
6✔
151
                this.intl.t('preprints.detail.withdrawn_title', { title: preprint.title }) :
152
                preprint.title;
153

154
            const metaTagsData = {
6✔
155
                title: preprintTitle,
156
                description: preprint.description,
157
                publishedDate: moment(preprint.datePublished).format('YYYY-MM-DD'),
158
                modifiedDate: moment(preprint.dateModified).format('YYYY-MM-DD'),
159
                identifier: preprint.id,
160
                url: pathJoin(config.OSF.url, preprint.id),
161
                doi: doi && doi.value,
6!
162
                image,
163
                keywords: preprint.tags,
164
                siteName: 'OSF',
165
                license: license && (license as LicenseModel).name,
12✔
166
                author: (contributors as SparseModel[]).map(
167
                    contrib => (contrib.users as { fullName: string }).fullName,
24✔
168
                ),
169
            };
170

171
            const allTags: HeadTagDef[] = this.metaTags.getHeadTags(metaTagsData);
6✔
172

173
            if (provider && provider.assets && provider.assets.favicon) {
6!
174
                allTags.push({
×
175
                    type: 'link',
176
                    attrs: {
177
                        rel: 'icon',
178
                        href: provider.assets.favicon,
179
                    },
180
                });
181
            }
182
            this.set('headTags', allTags);
6✔
183
            this.metaTags.updateHeadTags();
6✔
184
            (this.controller as PrePrintsDetailController).plauditIsReady = true;
6✔
185
        }
186
        blocker.done();
6✔
187
    }
188

189
    afterModel(model: any) {
190
        if (!this.currentUser.viewOnlyToken) {
6!
191
            taskFor(this.setHeadTags).perform(model);
6✔
192
        }
193
    }
194
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc