diff --git a/.codespellignore b/.codespellignore new file mode 100644 index 000000000..84c62677a --- /dev/null +++ b/.codespellignore @@ -0,0 +1,2 @@ +iif +mane diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 000000000..d58726f2f --- /dev/null +++ b/.codespellrc @@ -0,0 +1,6 @@ +[codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = .git*,*.svg,*.lock,*.css,.codespellrc,*.js,generated,assets,variants-summary.page.html +check-hidden = true +# Ignore super long lines -- must be minimized etc +ignore-regex = ^.{120,}|\b(AllTime|allTime)\b diff --git a/.github/workflows/build_frontend.yml b/.github/workflows/build_frontend.yml index 89d9cf30d..78b01484b 100644 --- a/.github/workflows/build_frontend.yml +++ b/.github/workflows/build_frontend.yml @@ -21,7 +21,7 @@ jobs: with: working-directory: ./server bundler-cache: true - ruby-version: '3.0' + ruby-version: '3.3' - name: Setup node uses: actions/setup-node@v4 diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 000000000..3b6e3d522 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,25 @@ +# Codespell configuration is within .codespellrc +--- +name: Codespell + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Codespell + uses: codespell-project/actions-codespell@v2 + with: + ignore_words_file: .codespellignore diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0cfb64f25..9618475b6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -37,7 +37,7 @@ jobs: uses: ruby/setup-ruby@v1 with: working-directory: ./server - ruby-version: '3.0' + ruby-version: '3.3' bundler-cache: true - name: Deploy to production diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5a8c5f111..76146ddea 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,6 +23,9 @@ jobs: - name: 'Checkout code' uses: actions/checkout@v3 + - name: 'Setup elasticsearch' + uses: ankane/setup-elasticsearch@v1 + - name: 'Setup Ruby' uses: ruby/setup-ruby@v1 with: diff --git a/README.md b/README.md index d73e23ceb..0384b3aed 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ All content created in CIViC is, and will continue to be, freely available, with ## Getting Started CIViC is a Rails backend serving a GraphQL API to an Angular frontend. The same API that powers the frontend is available for anyone to use. The easiest way to get started is to experiment in the [GraphiQL user interface](https://civicdb.org/api/graphiql). You can also browse autogenerated documentation [here](https://griffithlab.github.io/civic-v2/). ### Dependencies -* Ruby >= 3.0 (recomended install via rbenv) +* Ruby >= 3.0 (recommended install via rbenv) * PostgreSQL >= 14 * Node >= 14 diff --git a/client/src/app/components/evidence/evidence-table/evidence-table.component.html b/client/src/app/components/evidence/evidence-table/evidence-table.component.html index 6ca70c499..7504c7380 100644 --- a/client/src/app/components/evidence/evidence-table/evidence-table.component.html +++ b/client/src/app/components/evidence/evidence-table/evidence-table.component.html @@ -402,7 +402,7 @@ nzLabel="Combined"> + nzLabel="Unknown"> diff --git a/client/src/app/components/therapies/my-chem-info/my-chem-info.component.html b/client/src/app/components/therapies/my-chem-info/my-chem-info.component.html index 6a13bfa09..63841f43b 100644 --- a/client/src/app/components/therapies/my-chem-info/my-chem-info.component.html +++ b/client/src/app/components/therapies/my-chem-info/my-chem-info.component.html @@ -9,7 +9,7 @@ {{chemInfo.chebiDefinition}} - + {{i}} diff --git a/client/src/app/core/utilities/closeable-tag-base.ts b/client/src/app/core/utilities/closeable-tag-base.ts index 3467cf8d2..899bc0f28 100644 --- a/client/src/app/core/utilities/closeable-tag-base.ts +++ b/client/src/app/core/utilities/closeable-tag-base.ts @@ -8,7 +8,7 @@ export abstract class BaseCloseableTag implements OnInit { popoverVisible = false abstract idFunction(): number - // TODO: implement as getter/setters to remove ngOnInit depdendency for virtual scroll cache + // TODO: implement as getter/setters to remove ngOnInit dependency for virtual scroll cache // Low priority as closable tags are not currently used in virtual scroll viewports. ngOnInit(): void { if (this.onCloseClicked) { diff --git a/client/src/app/core/utilities/enum-tooltips/get-evidence-enum-tooltip.ts b/client/src/app/core/utilities/enum-tooltips/get-evidence-enum-tooltip.ts index 3ab21b0ee..c0d0120e8 100644 --- a/client/src/app/core/utilities/enum-tooltips/get-evidence-enum-tooltip.ts +++ b/client/src/app/core/utilities/enum-tooltips/get-evidence-enum-tooltip.ts @@ -83,7 +83,7 @@ export const tooltips: tooltipMap = { }, } -// a map of tooltips that differ based on their display context (entity type, evidence/asssertion type) +// a map of tooltips that differ based on their display context (entity type, evidence/assertion type) export type ContextualTooltipMap = { [key: string | symbol]: { // TODO: type as [key in ContextualAttribute]?: { diff --git a/client/src/app/forms/components/form-errors-alert/form-errors-alert.component.html b/client/src/app/forms/components/form-errors-alert/form-errors-alert.component.html index fe5d3eb65..acb8bb925 100644 --- a/client/src/app/forms/components/form-errors-alert/form-errors-alert.component.html +++ b/client/src/app/forms/components/form-errors-alert/form-errors-alert.component.html @@ -8,7 +8,7 @@ *ngIf="errors.length > 1" [nzDescription]="errorList" nzShowIcon - nzMessage="Submit Errors Occured"> + nzMessage="Submit Errors Occurred"> Popover Closeable Checkable - Trucate + Truncate Group Unlinked diff --git a/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.config.ts b/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.config.ts index a54fd8fdc..14a727ec3 100644 --- a/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.config.ts +++ b/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.config.ts @@ -45,7 +45,7 @@ export const columnKeyToQueryVariableMap: EvidenceManagerColQueryMap = { therapies: 'therapyName', evidenceItem: 'id', } -// colum keys included here will be hidden in preference panel, preventing +// column keys included here will be hidden in preference panel, preventing // defaults from being changed by the user export const omittedFromPrefs: EvidenceManagerColKey[] = ['selected', 'id'] diff --git a/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.types.ts b/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.types.ts index b2db39006..f199a19cf 100644 --- a/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.types.ts +++ b/client/src/app/forms/types/evidence-select/evidence-manager/evidence-manager.types.ts @@ -177,7 +177,7 @@ interface TagConfig { // most entity tag cols can be customized using TagConfig. // if showStatus set to true, tag will display status styles. // NOTE: use BaseColumnConfig's 'context' option if it's necessary -// to render an entity tag in a column whos row[colKey] data +// to render an entity tag in a column whose row[colKey] data // is not a LinkableEntity, e.g. evidence-manager table's 'id' col interface EntityTagConfig { showStatus?: boolean // display tag status indicator styles @@ -314,7 +314,7 @@ export const colTypeGuards = { // These guard attributes on col options, currently not used // in the TypeGuard pipe, but in logic that handles column options. // FIXME(?): I had hoped that the discriminated union type ColumnOptionType -// above would have made guard functions like this unecessary, but I was unable to +// above would have made guard functions like this unnecessary, but I was unable to // write some of the generic cols/prefs handling functions w/o them. Not // sure if this is bc the types are not constructed properly. export const hasSortOptions: TypeGuard = ( diff --git a/client/src/app/forms/types/molecular-profile-select/mp-expression-editor/mp-expression-editor.component.ts b/client/src/app/forms/types/molecular-profile-select/mp-expression-editor/mp-expression-editor.component.ts index bff727b9f..37df3a03f 100644 --- a/client/src/app/forms/types/molecular-profile-select/mp-expression-editor/mp-expression-editor.component.ts +++ b/client/src/app/forms/types/molecular-profile-select/mp-expression-editor/mp-expression-editor.component.ts @@ -238,7 +238,7 @@ export class MpExpressionEditorComponent implements AfterViewInit, OnChanges { ) .subscribe((res) => { // FIXME: this casting of 'res' is a total hack, need proper gate functions for this error/response - // logic, or refactor the parser to use rxjs error handling (which will also simplfy template logic) + // logic, or refactor the parser to use rxjs error handling (which will also simplify template logic) if (this.isMpParseError(res)) { const err = res as MpParseError this.expressionMessage$.next(undefined) diff --git a/client/src/app/forms/types/org-submit-button/org-submit-button.type.ts b/client/src/app/forms/types/org-submit-button/org-submit-button.type.ts index a6700d703..843c51c3b 100644 --- a/client/src/app/forms/types/org-submit-button/org-submit-button.type.ts +++ b/client/src/app/forms/types/org-submit-button/org-submit-button.type.ts @@ -68,7 +68,7 @@ export class CvcOrgSubmitButtonComponent organizations$: Observable mostRecentOrg$: Observable> - // these syncronize submit button & org dropdown button states, styles + // these synchronize submit button & org dropdown button states, styles isDisabled$: Subject isHidden$: Subject buttonClass$!: BehaviorSubject diff --git a/client/src/app/forms/types/variant-select/variant-manager/variant-manager.config.ts b/client/src/app/forms/types/variant-select/variant-manager/variant-manager.config.ts index 92fd34ac7..927725996 100644 --- a/client/src/app/forms/types/variant-select/variant-manager/variant-manager.config.ts +++ b/client/src/app/forms/types/variant-select/variant-manager/variant-manager.config.ts @@ -41,7 +41,7 @@ export const columnKeyToQueryVariableMap: VariantManagerColQueryMap = { aliases: 'variantAlias' } -// colum keys included here will be hidden in preference panel, preventing +// column keys included here will be hidden in preference panel, preventing // defaults from being changed by the user export const omittedFromPrefs: VariantManagerColKey[] = ['selected', 'id'] diff --git a/client/src/app/forms/types/variant-select/variant-manager/variant-manager.types.ts b/client/src/app/forms/types/variant-select/variant-manager/variant-manager.types.ts index 876069a70..e4de0833f 100644 --- a/client/src/app/forms/types/variant-select/variant-manager/variant-manager.types.ts +++ b/client/src/app/forms/types/variant-select/variant-manager/variant-manager.types.ts @@ -184,7 +184,7 @@ interface TagConfig { // most entity tag cols can be customized using TagConfig. // if showStatus set to true, tag will display status styles. // NOTE: use BaseColumnConfig's 'context' option if it's necessary -// to render an entity tag in a column whos row[colKey] data +// to render an entity tag in a column whose row[colKey] data // is not a LinkableEntity, e.g. variant-manager table's 'id' col interface EntityTagConfig { showStatus?: boolean // display tag status indicator styles @@ -329,7 +329,7 @@ export const colTypeGuards = { // These guard attributes on col options, currently not used // in the TypeGuard pipe, but in logic that handles column options. // FIXME(?): I had hoped that the discriminated union type ColumnOptionType -// above would have made guard functions like this unecessary, but I was unable to +// above would have made guard functions like this unnecessary, but I was unable to // write some of the generic cols/prefs handling functions w/o them. Not // sure if this is bc the types are not constructed properly. export const hasSortOptions: TypeGuard = ( diff --git a/client/src/app/forms/wrappers/form-row/form-row.wrapper.ts b/client/src/app/forms/wrappers/form-row/form-row.wrapper.ts index 9f86c5a52..ae2764499 100644 --- a/client/src/app/forms/wrappers/form-row/form-row.wrapper.ts +++ b/client/src/app/forms/wrappers/form-row/form-row.wrapper.ts @@ -19,7 +19,7 @@ type ResponsiveColConfig = { type FormRowOptions = { // nz-row gutter gutter?: number | [number, number] | null - // NOTE: if gutter[1] (vertial gutter) is set to 0, row will receive no top margin (see mp-finder config) + // NOTE: if gutter[1] (vertical gutter) is set to 0, row will receive no top margin (see mp-finder config) // nz-col's nzSpan, nzXs - nzXXl config applied to every field span?: string | number | null responsive?: ResponsiveColConfig diff --git a/client/src/app/generated/server.model.graphql b/client/src/app/generated/server.model.graphql index 8bcf48d22..21052edd9 100644 --- a/client/src/app/generated/server.model.graphql +++ b/client/src/app/generated/server.model.graphql @@ -93,7 +93,7 @@ The connection type for ActivityInterface. """ type ActivityInterfaceConnection { """ - List of activity types that have occured on this entity. + List of activity types that have occurred on this entity. """ activityTypes: [ActivityTypeInput!]! @@ -2435,7 +2435,7 @@ type EventConnection { edges: [EventEdge!]! """ - List of event types that have occured on this entity. + List of event types that have occurred on this entity. """ eventTypes: [EventAction!]! @@ -5124,7 +5124,7 @@ type LeaderboardUser { first: Int """ - Filter the reponse to include only notifications generated by a particular subscription. + Filter the response to include only notifications generated by a particular subscription. """ includeSeen: Boolean = false @@ -5134,12 +5134,12 @@ type LeaderboardUser { last: Int """ - Filter the response to include only notifications of a certaint type (ex: mentions). + Filter the response to include only notifications of a certain type (ex: mentions). """ notificationType: NotificationReason """ - Filter the reponse to include only notifications generated by a particular subscription. + Filter the response to include only notifications generated by a particular subscription. """ subscriptionId: Int ): NotificationConnection @@ -5759,7 +5759,7 @@ enum MolecularProfileDisplayFilter { WITH_ACCEPTED_OR_SUBMITTED """ - Display molecular profiles which have at least one submited evidence item. + Display molecular profiles which have at least one submitted evidence item. """ WITH_SUBMITTED } @@ -6009,7 +6009,7 @@ type Mutation { ): RejectRevisionsPayload """ - Resolve a flag on a CIViC entity indicating that it was either erronously flagged or the issue has been resolved. + Resolve a flag on a CIViC entity indicating that it was either erroneously flagged or the issue has been resolved. Any user may resolve their own flag however only editors with valid conflict of interest statements can resolve other flags. """ @@ -6161,7 +6161,7 @@ type Mutation { ): UnsubscribePayload """ - Update the currentlly logged in User's Conflict of Interest statement + Update the currently logged in User's Conflict of Interest statement """ updateCoi( """ @@ -6327,7 +6327,7 @@ type NotificationConnection { edges: [NotificationEdge!]! """ - List of event types that have occured on this entity. + List of event types that have occurred on this entity. """ eventTypes: [EventAction!]! @@ -6889,6 +6889,8 @@ type Query { """ last: Int mode: EventFeedMode + occuredAfter: ISO8601DateTime + occuredBefore: ISO8601DateTime organizationId: [Int!] """ @@ -10256,7 +10258,7 @@ type User { first: Int """ - Filter the reponse to include only notifications generated by a particular subscription. + Filter the response to include only notifications generated by a particular subscription. """ includeSeen: Boolean = false @@ -10266,12 +10268,12 @@ type User { last: Int """ - Filter the response to include only notifications of a certaint type (ex: mentions). + Filter the response to include only notifications of a certain type (ex: mentions). """ notificationType: NotificationReason """ - Filter the reponse to include only notifications generated by a particular subscription. + Filter the response to include only notifications generated by a particular subscription. """ subscriptionId: Int ): NotificationConnection diff --git a/client/src/app/generated/server.schema.json b/client/src/app/generated/server.schema.json index 3627d3e04..2e42fee92 100644 --- a/client/src/app/generated/server.schema.json +++ b/client/src/app/generated/server.schema.json @@ -728,7 +728,7 @@ "fields": [ { "name": "activityTypes", - "description": "List of activity types that have occured on this entity.", + "description": "List of activity types that have occurred on this entity.", "args": [], "type": { "kind": "NON_NULL", @@ -12508,7 +12508,7 @@ }, { "name": "eventTypes", - "description": "List of event types that have occured on this entity.", + "description": "List of event types that have occurred on this entity.", "args": [], "type": { "kind": "NON_NULL", @@ -23716,7 +23716,7 @@ }, { "name": "notificationType", - "description": "Filter the response to include only notifications of a certaint type (ex: mentions).", + "description": "Filter the response to include only notifications of a certain type (ex: mentions).", "type": { "kind": "ENUM", "name": "NotificationReason", @@ -23740,7 +23740,7 @@ }, { "name": "subscriptionId", - "description": "Filter the reponse to include only notifications generated by a particular subscription.", + "description": "Filter the response to include only notifications generated by a particular subscription.", "type": { "kind": "SCALAR", "name": "Int", @@ -23752,7 +23752,7 @@ }, { "name": "includeSeen", - "description": "Filter the reponse to include only notifications generated by a particular subscription.", + "description": "Filter the response to include only notifications generated by a particular subscription.", "type": { "kind": "SCALAR", "name": "Boolean", @@ -26730,7 +26730,7 @@ }, { "name": "WITH_SUBMITTED", - "description": "Display molecular profiles which have at least one submited evidence item.", + "description": "Display molecular profiles which have at least one submitted evidence item.", "isDeprecated": false, "deprecationReason": null }, @@ -27530,7 +27530,7 @@ }, { "name": "resolveFlag", - "description": "Resolve a flag on a CIViC entity indicating that it was either erronously flagged or the issue has been resolved.\nAny user may resolve their own flag however only editors with valid conflict of interest statements can resolve other flags.", + "description": "Resolve a flag on a CIViC entity indicating that it was either erroneously flagged or the issue has been resolved.\nAny user may resolve their own flag however only editors with valid conflict of interest statements can resolve other flags.", "args": [ { "name": "input", @@ -27965,7 +27965,7 @@ }, { "name": "updateCoi", - "description": "Update the currentlly logged in User's Conflict of Interest statement", + "description": "Update the currently logged in User's Conflict of Interest statement", "args": [ { "name": "input", @@ -29875,7 +29875,7 @@ }, { "name": "eventTypes", - "description": "List of event types that have occured on this entity.", + "description": "List of event types that have occurred on this entity.", "args": [], "type": { "kind": "NON_NULL", @@ -32157,6 +32157,30 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "occuredBefore", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ISO8601DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "occuredAfter", + "description": null, + "type": { + "kind": "SCALAR", + "name": "ISO8601DateTime", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "mode", "description": null, @@ -46310,7 +46334,7 @@ }, { "name": "notificationType", - "description": "Filter the response to include only notifications of a certaint type (ex: mentions).", + "description": "Filter the response to include only notifications of a certain type (ex: mentions).", "type": { "kind": "ENUM", "name": "NotificationReason", @@ -46334,7 +46358,7 @@ }, { "name": "subscriptionId", - "description": "Filter the reponse to include only notifications generated by a particular subscription.", + "description": "Filter the response to include only notifications generated by a particular subscription.", "type": { "kind": "SCALAR", "name": "Int", @@ -46346,7 +46370,7 @@ }, { "name": "includeSeen", - "description": "Filter the reponse to include only notifications generated by a particular subscription.", + "description": "Filter the response to include only notifications generated by a particular subscription.", "type": { "kind": "SCALAR", "name": "Boolean", diff --git a/client/src/app/views/assertions/assertions-detail/assertions-summary/assertions-summary.page.html b/client/src/app/views/assertions/assertions-detail/assertions-summary/assertions-summary.page.html index ecc3b52a7..99b499f70 100644 --- a/client/src/app/views/assertions/assertions-detail/assertions-summary/assertions-summary.page.html +++ b/client/src/app/views/assertions/assertions-detail/assertions-summary/assertions-summary.page.html @@ -1,7 +1,7 @@ - + diff --git a/client/src/app/views/features/features-home/features-home.page.html b/client/src/app/views/features/features-home/features-home.page.html index a3807b1e7..4b4c06cc3 100644 --- a/client/src/app/views/features/features-home/features-home.page.html +++ b/client/src/app/views/features/features-home/features-home.page.html @@ -23,7 +23,7 @@

Features

nzExpandable [nzEllipsisRows]="2"> CIViC Features include a feature-level summary, a link to the Drug - Gene Interation Database, and extensive gene details from MyGene.info. + Gene InteractionDatabase, and extensive gene details from MyGene.info.

Data Releases dynamically obtained from resources external to CIViC (e.g. MyVariant.Info, MyGene.Info). Variant TSV releases only include variant records with accepted evidence records. Variant TSV releases - from before August 2020 include all variant records, irregardless of + from before August 2020 include all variant records, regardless of the status of the associated evidence items. Evidence TSV releases only include accepted evidence items and exclude pending or rejected evidence items. Assertion TSV releases only include accepted diff --git a/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-summary/variant-groups-summary.page.html b/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-summary/variant-groups-summary.page.html index f470b8877..7908f23ee 100644 --- a/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-summary/variant-groups-summary.page.html +++ b/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-summary/variant-groups-summary.page.html @@ -77,7 +77,7 @@ + cvcTitle="Variants in Variant Group {{variantGroup?.name}}">
diff --git a/client/src/main.ts b/client/src/main.ts index d6c991ae2..cbafacfb3 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -8,7 +8,7 @@ import { environment } from './environments/environment' if (environment.production) { enableProdMode() } else { - // enable RXjs Spy on non production bulds only + // enable RXjs Spy on non production builds only const spy = create() // deactivate CyclePlugin, which spams console w/ // an alert about a next cycle in table-scroll.directive. diff --git a/client/src/themes/overrides/entity-page-header.overrides.less b/client/src/themes/overrides/entity-page-header.overrides.less index ffac33913..83b84ac09 100644 --- a/client/src/themes/overrides/entity-page-header.overrides.less +++ b/client/src/themes/overrides/entity-page-header.overrides.less @@ -31,7 +31,7 @@ } .header-description { padding: @default-padding-sm; - // adjust headline and desctiption to fit nicely with + // adjust headline and description to fit nicely with // the larger icon h2 { color: #262626; diff --git a/server/Gemfile b/server/Gemfile index 3b322e9dd..046a1fa9f 100644 --- a/server/Gemfile +++ b/server/Gemfile @@ -47,7 +47,7 @@ gem 'trestle', '~>0.9.5' gem 'trestle-search', '~>0.4.3' #elasticsearch -gem 'searchkick', '~> 4.5.0' +gem 'searchkick', '~> 5.3.0' gem 'elasticsearch', '~> 7.13.0' gem 'typhoeus', '~>1.4.0' diff --git a/server/Gemfile.lock b/server/Gemfile.lock index 562ca7d98..51dca730e 100644 --- a/server/Gemfile.lock +++ b/server/Gemfile.lock @@ -437,9 +437,8 @@ GEM search_object_graphql (1.0.5) graphql (> 1.8) search_object (~> 1.2.5) - searchkick (4.5.2) - activemodel (>= 5) - elasticsearch (>= 6) + searchkick (5.3.1) + activemodel (>= 6.1) hashie semantic_range (3.0.0) sidekiq (7.2.2) @@ -579,7 +578,7 @@ DEPENDENCIES sass-rails (>= 6) scenic (~> 1.5.4) search_object_graphql (= 1.0.5) - searchkick (~> 4.5.0) + searchkick (~> 5.3.0) sidekiq (< 8) sidekiq-cron (~> 1.10.0) simplecov diff --git a/server/app/graphql/loaders/association_count_loader.rb b/server/app/graphql/loaders/association_count_loader.rb index a36e53b87..c18f215f4 100644 --- a/server/app/graphql/loaders/association_count_loader.rb +++ b/server/app/graphql/loaders/association_count_loader.rb @@ -1,6 +1,6 @@ module Loaders class AssociationCountLoader < GraphQL::Batch::Loader - def initialize(model, association: assocation) + def initialize(model, association: ) @model = model @association = association end diff --git a/server/app/graphql/mutations/resolve_flag.rb b/server/app/graphql/mutations/resolve_flag.rb index 731dd5d39..d4952451d 100644 --- a/server/app/graphql/mutations/resolve_flag.rb +++ b/server/app/graphql/mutations/resolve_flag.rb @@ -1,6 +1,6 @@ class Mutations::ResolveFlag < Mutations::MutationWithOrg description <<~DOC.strip - Resolve a flag on a CIViC entity indicating that it was either erronously flagged or the issue has been resolved. + Resolve a flag on a CIViC entity indicating that it was either erroneously flagged or the issue has been resolved. Any user may resolve their own flag however only editors with valid conflict of interest statements can resolve other flags. DOC diff --git a/server/app/graphql/mutations/update_coi.rb b/server/app/graphql/mutations/update_coi.rb index 28134808d..53063458e 100644 --- a/server/app/graphql/mutations/update_coi.rb +++ b/server/app/graphql/mutations/update_coi.rb @@ -1,5 +1,5 @@ class Mutations::UpdateCoi < Mutations::BaseMutation - description "Update the currentlly logged in User's Conflict of Interest statement" + description "Update the currently logged in User's Conflict of Interest statement" argument :coi_present, Boolean, required: true, description: 'Does the user report having a conflict of interest? Mark true if so.' diff --git a/server/app/graphql/resolvers/activities.rb b/server/app/graphql/resolvers/activities.rb index 33b4deed9..1fe56d5f2 100644 --- a/server/app/graphql/resolvers/activities.rb +++ b/server/app/graphql/resolvers/activities.rb @@ -37,8 +37,16 @@ class Activities < GraphQL::Schema::Resolver scope.where(subject: value) end + option(:occured_before, type: GraphQL::Types::ISO8601DateTime) do |scope, value| + scope.where("activities.created_at <= ?", value) + end + + option(:occured_after, type: GraphQL::Types::ISO8601DateTime) do |scope, value| + scope.where("activities.created_at >= ?", value) + end + option(:mode, type: Types::Events::EventFeedMode) do |_, _| - #accesed in connection, yuck + #accessed in connection, yuck end end end diff --git a/server/app/graphql/resolvers/top_level_events.rb b/server/app/graphql/resolvers/top_level_events.rb index 2c7f76398..ba7927894 100644 --- a/server/app/graphql/resolvers/top_level_events.rb +++ b/server/app/graphql/resolvers/top_level_events.rb @@ -44,6 +44,6 @@ class Resolvers::TopLevelEvents < GraphQL::Schema::Resolver end option(:mode, type: Types::Events::EventFeedMode) do |_, _| - #accesed in connection, yuck + #accessed in connection, yuck end end diff --git a/server/app/graphql/resolvers/top_level_therapies.rb b/server/app/graphql/resolvers/top_level_therapies.rb index d4aff8a08..79212a228 100644 --- a/server/app/graphql/resolvers/top_level_therapies.rb +++ b/server/app/graphql/resolvers/top_level_therapies.rb @@ -9,12 +9,11 @@ class Resolvers::TopLevelTherapies < GraphQL::Schema::Resolver description 'List and filter Therapies from the NCI Thesaurus.' scope do - Therapy.select('therapies.id, therapies.name, therapies.ncit_id, count(distinct(assertions.id)) as assertion_count, count(distinct(evidence_items.id)) as evidence_count') - .left_outer_joins(:assertions) - .left_outer_joins(:evidence_items) + Therapy.select('therapies.id, therapies.name, max(therapies.ncit_id) as ncit_id, count(distinct(assertions.id)) as assertion_count, count(distinct(evidence_items.id)) as evidence_count') + .left_outer_joins(:assertions, :evidence_items) .where("evidence_items.status != 'rejected' OR assertions.status != 'rejected'") .where(deprecated: false) - .group('therapies.id, therapies.name, therapies.ncit_id') + .group('therapies.id, therapies.name') .having('COUNT(evidence_items.id) > 0 OR COUNT(assertions.id) > 0') .order('evidence_count DESC', :id) end diff --git a/server/app/graphql/types/connections/activities_connection.rb b/server/app/graphql/types/connections/activities_connection.rb index fdf726767..d2bdf2bd8 100644 --- a/server/app/graphql/types/connections/activities_connection.rb +++ b/server/app/graphql/types/connections/activities_connection.rb @@ -12,7 +12,7 @@ class ActivitiesConnection < Types::BaseConnection description: 'When filtered on a subject, user, or organization, the total number of events for that subject/user/organization, irregardless of other filters.' field :activity_types, [Types::Activities::ActivityTypeInputType], null: false, - description: 'List of activity types that have occured on this entity.' + description: 'List of activity types that have occurred on this entity.' field :subject_types, [Types::Activities::ActivitySubjectInputType], null: false diff --git a/server/app/graphql/types/connections/events_connection.rb b/server/app/graphql/types/connections/events_connection.rb index fb7b93176..80654bedf 100644 --- a/server/app/graphql/types/connections/events_connection.rb +++ b/server/app/graphql/types/connections/events_connection.rb @@ -6,7 +6,7 @@ class EventsConnection < Types::BaseConnection description: 'List of all users that have generated an event on the subject entity.' field :event_types, [Types::Events::EventActionType], null: false, - description: 'List of event types that have occured on this entity.' + description: 'List of event types that have occurred on this entity.' field :participating_organizations, [Types::Entities::OrganizationType], null: false, description: 'List of all organizations who are involved in this event stream.' diff --git a/server/app/graphql/types/connections/notifications_connection.rb b/server/app/graphql/types/connections/notifications_connection.rb index b75d5548d..f81b3e1ba 100644 --- a/server/app/graphql/types/connections/notifications_connection.rb +++ b/server/app/graphql/types/connections/notifications_connection.rb @@ -9,7 +9,7 @@ class NotificationsConnection < Types::BaseConnection description: 'Users who have performed an action (other than a mention) that created a notification.' field :event_types, [Types::Events::EventActionType], null: false, - description: 'List of event types that have occured on this entity.' + description: 'List of event types that have occurred on this entity.' field :organizations, [Types::Entities::OrganizationType], null: false, description: 'List of all organizations who are involved in this notification stream.' diff --git a/server/app/graphql/types/entities/user_type.rb b/server/app/graphql/types/entities/user_type.rb index a9a3ac31c..fd49eff07 100644 --- a/server/app/graphql/types/entities/user_type.rb +++ b/server/app/graphql/types/entities/user_type.rb @@ -41,8 +41,8 @@ def authorized?(object, args, context) field :notifications, Types::Entities::NotificationType.connection_type, null: true do description 'Filterable list of notifications for the logged in user.' - type_desc = 'Filter the response to include only notifications of a certaint type (ex: mentions).' - sub_desc = 'Filter the reponse to include only notifications generated by a particular subscription.' + type_desc = 'Filter the response to include only notifications of a certain type (ex: mentions).' + sub_desc = 'Filter the response to include only notifications generated by a particular subscription.' event_desc = 'Filter the response to include only notifications generated by certain actions (ex: commenting).' argument :notification_type, Types::NotificationReasonType, required: false, description: type_desc diff --git a/server/app/graphql/types/molecular_profile_display_filter_type.rb b/server/app/graphql/types/molecular_profile_display_filter_type.rb index 1421a2568..1fde9f7fd 100644 --- a/server/app/graphql/types/molecular_profile_display_filter_type.rb +++ b/server/app/graphql/types/molecular_profile_display_filter_type.rb @@ -5,7 +5,7 @@ class MolecularProfileDisplayFilterType < Types::BaseEnum value 'WITH_ACCEPTED_OR_SUBMITTED', description: 'Display only molecular profiles which have evidence in either an accepted or submitted state.' value 'WITH_SUBMITTED', - description: 'Display molecular profiles which have at least one submited evidence item.' + description: 'Display molecular profiles which have at least one submitted evidence item.' value 'ALL', description: 'Display all molecular profiles regardless of attached evidence status.' end diff --git a/server/app/lib/importer/disease_ontology_mirror.rb b/server/app/lib/importer/disease_ontology_mirror.rb index ff85c3b57..0b1036e60 100644 --- a/server/app/lib/importer/disease_ontology_mirror.rb +++ b/server/app/lib/importer/disease_ontology_mirror.rb @@ -79,7 +79,7 @@ def assign_synonyms(disease, synonyms) end def delete_unprocessed_diseases - #sanity check for the DOID api, bail early if we cant find "cancer" + #sanity check for the DOID api, bail early if we can't find "cancer" uri = URI(url_from_doid(162)) resp = Net::HTTP.get_response(uri) if resp.code != '200' diff --git a/server/app/models/molecular_profile.rb b/server/app/models/molecular_profile.rb index f18e62651..53328abc0 100644 --- a/server/app/models/molecular_profile.rb +++ b/server/app/models/molecular_profile.rb @@ -36,7 +36,7 @@ class MolecularProfile < ActiveRecord::Base validate :unique_name_in_context searchkick highlight: [:name, :aliases], callbacks: :async, word_start: [:name] - scope :search_import, -> { includes(:molecular_profile_aliases, variants: [:gene])} + scope :search_import, -> { includes(:molecular_profile_aliases, variants: [:feature])} after_create -> { MaterializedViews::MolecularProfileBrowseTableRow.refresh_async } diff --git a/server/app/models/my_chem_info.rb b/server/app/models/my_chem_info.rb index 891eee81f..704cd5464 100644 --- a/server/app/models/my_chem_info.rb +++ b/server/app/models/my_chem_info.rb @@ -22,7 +22,7 @@ def response def parse_response(resp) p = JSON.parse(resp) if p['hits'] && p['hits'].size > 1 - return nil #it was ambiguous somehow, shouldnt happen with a NCIT + return nil #it was ambiguous somehow, shouldn't happen with a NCIT end if p['hits'] && p['hits'].size == 1 diff --git a/server/app/models/my_disease_info.rb b/server/app/models/my_disease_info.rb index dda2fa5f5..7cf5c196f 100644 --- a/server/app/models/my_disease_info.rb +++ b/server/app/models/my_disease_info.rb @@ -22,7 +22,7 @@ def response def parse_response(resp) p = JSON.parse(resp) if p['hits'] && p['hits'].size > 1 - return nil #it was ambiguous somehow, shouldnt happen with a DOID + return nil #it was ambiguous somehow, shouldn't happen with a DOID end if p['hits'] && p['hits'].size == 1 diff --git a/server/app/utilities/merge_accounts.rb b/server/app/utilities/merge_accounts.rb index a8662b258..c9c057afd 100644 --- a/server/app/utilities/merge_accounts.rb +++ b/server/app/utilities/merge_accounts.rb @@ -5,7 +5,7 @@ def self.name end def self.description - "Merge two user accounts, removing one and transfering the authorizations and events to the remaining one." + "Merge two user accounts, removing one and transferring the authorizations and events to the remaining one." end def self.inputs diff --git a/server/config/environments/test.rb b/server/config/environments/test.rb index 93ed4f1b7..f8ecd679c 100644 --- a/server/config/environments/test.rb +++ b/server/config/environments/test.rb @@ -11,10 +11,8 @@ config.cache_classes = false config.action_view.cache_template_loading = true - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false + # Eager load when running in CI to detect any load issues + config.eager_load = ENV["CI"].present? # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true @@ -27,8 +25,7 @@ config.action_controller.perform_caching = false config.cache_store = :null_store - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false + config.action_dispatch.show_exceptions = true # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false @@ -49,6 +46,8 @@ # Raise exceptions for disallowed deprecations. config.active_support.disallowed_deprecation = :raise + config.active_job.queue_adapter = :test + # Tell Active Support which deprecation messages to disallow. config.active_support.disallowed_deprecation_warnings = [] diff --git a/server/config/initializers/trestle.rb b/server/config/initializers/trestle.rb index 6b6276d24..a355980f9 100644 --- a/server/config/initializers/trestle.rb +++ b/server/config/initializers/trestle.rb @@ -16,7 +16,7 @@ # # config.site_logo_small = "logo-small.png" - # Speficy a favicon to be used within the admin. + # Specify a favicon to be used within the admin. # # config.favicon = "favicon.ico" diff --git a/server/config/query_examples/evidence_counts.yml b/server/config/query_examples/evidence_counts.yml index ff02c8a63..0170ed807 100644 --- a/server/config/query_examples/evidence_counts.yml +++ b/server/config/query_examples/evidence_counts.yml @@ -22,4 +22,5 @@ query: | } } } + } diff --git a/server/test/controllers/.keep b/server/test/controllers/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/server/test/controllers/links_controller_test.rb b/server/test/controllers/links_controller_test.rb new file mode 100644 index 000000000..3fb37dfcd --- /dev/null +++ b/server/test/controllers/links_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class LinksControllerTest < ActionDispatch::IntegrationTest + test "it should 404 rather than redirect when the entity isn't found" do + get "/links/features/999999" + assert_response :not_found + end + + test 'it should 400 bad request when its an invalid link type' do + get '/links/footures/9999' + assert_response :bad_request + end + + test 'gene, feature, factor permalinks work' do + feature = features.first + feature_path = "/features/#{feature.id}" + check_redirect "/links/features/#{feature.id}", feature_path + check_redirect "/links/id/FID#{feature.id}", feature_path + + gene = feature_genes.first + gene_path = "/features/#{gene.feature.id}" + check_redirect "/links/genes/#{gene.id}", gene_path + check_redirect "/links/id/GID#{gene.id}", gene_path + check_redirect "/links/entrez_id/#{gene.entrez_id}", gene_path + check_redirect "/links/entrez_name/#{gene.name}", gene_path + end + + test 'variant links work' do + variant = variants(:v600e) + variant_path = "/variants/#{variant.id}" + + check_redirect "/links/id/VID#{variant.id}", variant_path + check_redirect "/links/allele_registry/#{variant.allele_registry_id}", variant_path + check_redirect "/links/variants/#{variant.id}", variant_path + end + + test 'redirect legacy frontend gene route to corresponding feature' do + gene = feature_genes.first + check_redirect "/genes/#{gene.id}", "/features/#{gene.feature.id}" + end + + def check_redirect(input_path, output_path) + get input_path + assert_response :redirect + redirect_url = URI.parse(@response['Location']).path + assert_equal output_path, redirect_url + end +end diff --git a/server/test/fixtures/feature_factors.yml b/server/test/fixtures/feature_factors.yml new file mode 100644 index 000000000..07b3349b8 --- /dev/null +++ b/server/test/fixtures/feature_factors.yml @@ -0,0 +1,3 @@ +msi: + ncit_id: NCIT123 + diff --git a/server/test/fixtures/features.yml b/server/test/fixtures/features.yml index ae7587d88..86ffe0e40 100644 --- a/server/test/fixtures/features.yml +++ b/server/test/fixtures/features.yml @@ -1,8 +1,15 @@ braf: name: BRAF + full_name: B-Raf proto-oncogene, serine/threonine kinase feature_instance: braf (Features::Gene) vhl: name: VHL + full_name: von Hippel-Lindau tumor suppressor feature_instance: vhl (Features::Gene) +msi: + name: MSI + full_name: Microsatellite Instability + description: The description for the MSI factor + feature_instance: msi (Features::Factor) diff --git a/server/test/fixtures/variants.yml b/server/test/fixtures/variants.yml index 3c29e5c65..eff1e065d 100644 --- a/server/test/fixtures/variants.yml +++ b/server/test/fixtures/variants.yml @@ -1,23 +1,28 @@ v600e: name: V600E feature: braf - gene: braf + gene_id: 1 + type: 'Variants::GeneVariant' single_variant_molecular_profile: mp1 + allele_registry_id: CAFOO v600k: name: V600K feature: braf - gene: braf + gene_id: 1 + type: 'Variants::GeneVariant' single_variant_molecular_profile: mp2 w88: name: W88* feature: vhl - gene: vhl + gene_id: 2 + type: 'Variants::GeneVariant' single_variant_molecular_profile: mp3 v87e: name: V87E (c.260T>A) feature: vhl - gene: vhl + gene_id: 2 + type: 'Variants::GeneVariant' single_variant_molecular_profile: mp4 diff --git a/server/test/graphql/example_queries_test.rb b/server/test/graphql/example_queries_test.rb new file mode 100644 index 000000000..8460c3272 --- /dev/null +++ b/server/test/graphql/example_queries_test.rb @@ -0,0 +1,17 @@ +require "test_helper" + +class ExampleQueriesTest < ActiveSupport::TestCase + def setup + MolecularProfile.reindex + path = File.join(Rails.root, 'config', 'query_examples') + @queries = GqlExamples.new(path) + end + + test "graphiql example queries" do + @queries.examples.each do |q| + query = q["query"] + resp = Civic2Schema.execute(query) + assert_nil(resp["errors"]) + end + end +end diff --git a/server/test/graphql/mutations/create_molecular_profile_test.rb b/server/test/graphql/mutations/create_molecular_profile_test.rb index 699e9f089..ff960447d 100644 --- a/server/test/graphql/mutations/create_molecular_profile_test.rb +++ b/server/test/graphql/mutations/create_molecular_profile_test.rb @@ -22,7 +22,7 @@ def setup mp_id = response["data"]["createMolecularProfile"]["molecularProfile"]['id'] mp = MolecularProfile.find(mp_id) assert_equal(mp.display_name, "BRAF V600E") - assert_equal(mp.variants, [@variant]) + assert_equal(mp.variants.to_a, [@variant]) end test "must be logged in" do @@ -66,7 +66,7 @@ def setup mp_id = response["data"]["createMolecularProfile"]["molecularProfile"]["id"] mp = MolecularProfile.find(mp_id) assert_equal(mp.display_name, "NOT BRAF V600K AND BRAF V600E AND ( VHL W88* OR VHL V87E (c.260T>A) )") - assert_equal(mp.variants, [@variant, v2, v3, v4]) + assert_equal(mp.variants.to_a, [@variant, v2, v3, v4]) end test "ordering should be deterministic, at least in variant components" do @@ -106,6 +106,6 @@ def setup mp_id = response["data"]["createMolecularProfile"]["molecularProfile"]['id'] mp = MolecularProfile.find(mp_id) assert_equal(mp.display_name, "NOT BRAF V600K AND BRAF V600E AND ( VHL W88* OR VHL V87E (c.260T>A) )") - assert_equal(mp.variants, [@variant, v2, v3, v4]) + assert_equal(mp.variants.to_a, [@variant, v2, v3, v4]) end end diff --git a/server/test/test_helper.rb b/server/test/test_helper.rb index 1871f96f7..b96f9cff2 100644 --- a/server/test/test_helper.rb +++ b/server/test/test_helper.rb @@ -7,6 +7,7 @@ class ActiveSupport::TestCase fixtures :all set_fixture_class feature_genes: Features::Gene + set_fixture_class feature_factors: Features::Factor # Add more helper methods to be used by all tests here... end