Skip to content

Commit

Permalink
Merge pull request #1107 from geonetwork/duplicate-attachments
Browse files Browse the repository at this point in the history
Save records on creation/duplication and allow attachments
  • Loading branch information
cmoinier authored Feb 10, 2025
2 parents 9ee0df3 + 958b57b commit 2804667
Show file tree
Hide file tree
Showing 54 changed files with 1,179 additions and 887 deletions.
99 changes: 47 additions & 52 deletions apps/metadata-editor-e2e/src/e2e/dashboard.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,58 +146,6 @@ describe('dashboard (authenticated)', () => {
)
})
})
describe('columns', () => {
beforeEach(() => {
cy.visit('/catalog/search')
})
it('should display the right info for unpublished records', () => {
cy.get('[data-cy="create-record"]').click()
cy.get('gn-ui-form-field[ng-reflect-model=abstract] textarea')
.as('abstractField')
.focus()
cy.get('@abstractField').type('draft abstract')
cy.editor_findDraftInLocalStorage().then((value) => {
expect(value).to.contain('draft abstract')
})
cy.visit('/my-space/my-draft')
cy.get('gn-ui-results-table').find('[data-cy="table-row"]').as('draft')
cy.get('@draft').should('have.length', 1)
cy.get('@draft')
.children('div')
.eq(4)
.find('span')
.invoke('text')
.should('eq', '')
cy.get('@draft')
.children('div')
.eq(5)
.should('include.text', 'Not published')
cy.get('@draft').children('div').eq(6).should('contain', ' - ')
cy.clearRecordDrafts()
})
it('should display the right info for published records', () => {
cy.visit('/catalog/search')
cy.get('md-editor-dashboard-menu').find('a').eq(5).click()
cy.get('gn-ui-results-table')
.find('[data-cy="table-row"]')
.first()
.as('record')
cy.get('@record')
.children('div')
.eq(4)
.find('span')
.invoke('text')
.should('eq', 'admin admin')
cy.get('@record')
.children('div')
.eq(5)
.find('span')
.should('include.text', 'Published')
cy.get('@record').children('div').eq(6).should('not.contain', ' - ')
cy.clearRecordDrafts()
})
})

describe('navigation', () => {
beforeEach(() => {
cy.visit('/catalog/search')
Expand Down Expand Up @@ -244,6 +192,53 @@ describe('dashboard (authenticated)', () => {
})
})
})
describe('columns', () => {
beforeEach(() => {
cy.visit('/catalog/search')
})
it('should display the right info for unpublished records', () => {
cy.get('[data-cy="create-record"]').click()
cy.get('gn-ui-form-field[ng-reflect-model=abstract] textarea')
.as('abstractField')
.focus()
cy.get('@abstractField').type('draft abstract')
cy.visit('/catalog/search')
cy.get('gn-ui-results-table').find('[data-cy="table-row"]').as('records')
cy.get('@records')
.children('div')
.eq(4)
.find('span')
.invoke('text')
.should('eq', 'admin admin')
cy.get('@records')
.children('div')
.eq(5)
.should('include.text', 'Not published')
cy.get('@records').children('div').eq(6).should('contain', ' - ')
cy.clearRecordDrafts()
})
it('should display the right info for published records', () => {
cy.visit('/catalog/search')
cy.get('md-editor-dashboard-menu').find('a').eq(5).click()
cy.get('gn-ui-results-table')
.find('[data-cy="table-row"]')
.eq(1)
.as('record')
cy.get('@record')
.children('div')
.eq(4)
.find('span')
.invoke('text')
.should('eq', 'admin admin')
cy.get('@record')
.children('div')
.eq(5)
.find('span')
.should('include.text', 'Published')
cy.get('@record').children('div').eq(6).should('not.contain', ' - ')
cy.clearRecordDrafts()
})
})

describe('search', () => {
function checkDashboardFiltered() {
Expand Down
9 changes: 4 additions & 5 deletions apps/metadata-editor-e2e/src/e2e/edit.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ describe('editor form', () => {
.click()
cy.get('[data-test="record-menu-duplicate-button"]').click()
cy.url().should('include', '/duplicate/')
cy.editor_findDraftInLocalStorage().then((value) => {
expect(value).to.not.equal(null)
})
// because new records are saved by default, they are not drafts and can be published
cy.get('md-editor-publish-button').click()

// Open the copy
Expand Down Expand Up @@ -126,8 +124,8 @@ describe('editor form', () => {
.find('textarea')
.invoke('val')
.should(
'eq',
"Stations d'épuration selon la directive Eaux Résiduelles Urbaines (91/271/CEE) en Wallonie (Copy)"
'include',
"Copy of record Stations d'épuration selon la directive Eaux Résiduelles Urbaines (91/271/CEE) en Wallonie"
)
})
it('shows very long titles entirely', () => {
Expand Down Expand Up @@ -505,6 +503,7 @@ describe('editor form', () => {
cy.get('gn-ui-form-field-online-resources')
.find('gn-ui-url-input')
.find('input')
.first()
.type('http://example.com/wms')
cy.get('gn-ui-online-service-resource-input')
.find('[data-cy="identifier-in-service"]')
Expand Down
182 changes: 65 additions & 117 deletions apps/metadata-editor-e2e/src/e2e/record-actions.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,80 +8,64 @@ describe('record-actions', () => {
})
describe('delete', () => {
const recordId = `TEST_RECORD_${Date.now()}`
describe('record with draft', () => {
it('should delete the record, delete its associated draft and refresh the interface', () => {
// First create a record and its draft
cy.get('[data-cy="create-record"]').click()
cy.url().should('include', '/create')
cy.get('gn-ui-form-field[ng-reflect-model=abstract] textarea')
.as('abstractField')
.focus()
cy.get('@abstractField').type('record abstract')
cy.get('[data-test="recordTitleInput"]').click()
cy.get('[data-test="recordTitleInput"]').type('{selectAll}{backspace}')
cy.get('[data-test="recordTitleInput"]').type(recordId)
cy.intercept({
method: 'PUT',
pathname: '**/records',
}).as('insertRecord')
cy.get('md-editor-publish-button').click()
cy.wait('@insertRecord')
// Assert that the draft exists in the local storage
cy.editor_findDraftInLocalStorage().then((value) =>
expect(value).to.not.equal('null')
)
cy.get('@abstractField').focus()
cy.get('@abstractField').type('draft abstract')
cy.visit('/my-space/my-records')
cy.get('[data-cy="table-row"]')
.contains(recordId)
.should('have.length', 1)
cy.get('[data-cy="dashboard-drafts-count"]').should('contain', '1')
// Delete the record
cy.get('[data-test="record-menu-button"]').last().click()
cy.get('[data-test="record-menu-delete-button"]').click()
cy.get('[data-cy="confirm-button"]').click()
cy.get('[data-cy="table-row"]')
.contains(recordId)
.should('have.length', 0)
cy.get('gn-ui-notification').should('contain', 'Delete success')
})
})

describe('draft without record', () => {
it('should delete the draft and refresh the interface', () => {
// First create a draft
cy.get('[data-cy="create-record"]').click()
cy.url().should('include', '/create')
cy.get('[data-test="recordTitleInput"]').click()
cy.get('[data-test="recordTitleInput"]').type('{selectAll}{backspace}')
cy.get('[data-test="recordTitleInput"]').type(recordId)
cy.get('gn-ui-form-field[ng-reflect-model=abstract] textarea')
.as('abstractField')
.focus()
cy.get('@abstractField').type('draft abstract')
cy.editor_findDraftInLocalStorage().then((value) => {
expect(value).to.contain('draft abstract')
})
cy.visit('/my-space/my-draft')
cy.get('[data-cy="table-row"]')
.contains(recordId)
.should('have.length', 1)
cy.get('[data-cy="dashboard-drafts-count"]').should('contain', '1')
// Delete the draft
cy.get('[data-test="record-menu-button"]').click()
cy.get('[data-test="record-menu-delete-button"]').click()
cy.get('[data-cy="confirm-button"]').click()
cy.get('[data-cy="table-row"]').should('not.exist')
})
it('should delete the record, delete its associated draft and refresh the interface', () => {
// Create a record, make it draft
cy.get('[data-cy="create-record"]').click()
cy.get('gn-ui-form-field[ng-reflect-model=abstract] textarea')
.as('abstractField')
.focus()
cy.get('@abstractField').type('record abstract')
cy.get('[data-test="recordTitleInput"]').click()
cy.get('[data-test="recordTitleInput"]').type('{selectAll}{backspace}')
cy.get('[data-test="recordTitleInput"]').type(recordId)
cy.intercept({
method: 'PUT',
pathname: '**/records',
}).as('insertRecord')
cy.get('md-editor-publish-button').click()
cy.wait('@insertRecord')
// Assert that the draft exists in the local storage
cy.editor_findDraftInLocalStorage().then((value) =>
expect(value).to.not.equal('null')
)
cy.get('@abstractField').focus()
cy.get('@abstractField').type('draft abstract')
// Assert that the draft exists in the local storage
cy.editor_findDraftInLocalStorage().then((value) =>
expect(value).to.not.equal('null')
)
cy.visit('/my-space/my-records')
cy.get('[data-cy="table-row"]')
.contains(recordId)
.should('have.length', 1)
cy.get('[data-cy="dashboard-drafts-count"]').should('contain', '1')
// Delete the record
// as new records are always saved, it's not possible to delete them anymore from the draft page
cy.visit('/my-space/my-draft')
cy.get('[data-test="record-menu-button"]').click()
cy.get('[data-test="record-menu-delete-button"]')
.find('button')
.should('be.disabled')
// delete from my-records page
cy.visit('/my-space/my-records')
cy.get('[data-test="record-menu-button"]').last().click()
cy.get('[data-test="record-menu-delete-button"]').click()
cy.get('[data-cy="confirm-button"]').click()
cy.get('[data-cy="table-row"]')
.contains(recordId)
.should('have.length', 0)
cy.get('gn-ui-notification').should('contain', 'Delete success')
// check that draft was deleted
cy.visit('/my-space/my-draft')
cy.get('[data-cy="table-row"]').should('not.exist')
})
})

describe('create', () => {
beforeEach(() => {
// create a record
cy.get('[data-cy="create-record"]').click()
cy.url().should('include', '/create')
cy.url().should('include', '/edit')
})

afterEach(() => {
Expand Down Expand Up @@ -114,52 +98,6 @@ describe('record-actions', () => {
.should('contain.text', 'Next')
})

it('the created record should not allow upload of resources and show info message as it was not saved yet', () => {
// first page
cy.get('gn-ui-form-field-overviews')
.find('gn-ui-image-input')
.find('input')
.should('be.disabled')
cy.get('gn-ui-form-field-overviews')
.children()
.find('[data-test="disabled-message"]')
.should(
'contain.text',
' This field will be enabled once the dataset has been published '
)

// second page
cy.get('[data-test="previousNextPageButtons"]')
.children()
.eq(1)
.should('contain.text', 'Next')
.click()
cy.get('gn-ui-form-field-online-resources')
.find('gn-ui-switch-toggle')
.find('mat-button-toggle-group')
.find('button')
.should('be.disabled')
cy.get('gn-ui-file-input').find('input').should('be.disabled')
cy.get('gn-ui-form-field-online-resources')
.children()
.find('div')
.should(
'contain.text',
' This field will be enabled once the dataset has been published '
)

cy.get('gn-ui-form-field-online-link-resources')
.find('input')
.should('be.disabled')
cy.get('gn-ui-form-field-online-link-resources')
.children()
.find('div')
.should(
'contain.text',
' This field will be enabled once the dataset has been published '
)
})

it('back navigation should go to search after creating a record', () => {
cy.go('back')
cy.url().should('include', '/catalog/search')
Expand All @@ -180,13 +118,23 @@ describe('record-actions', () => {
.invoke('text')
.should('contain', 'admin admin')
})
it('the created record should display the uuid in the url, not create a draft and be saved but not published', () => {
cy.url().should('match', /\/edit\/.+/)
cy.get('[data-cy="dashboard-drafts-count"]').should('not.exist')
cy.get('[data-cy="save-status"]')
.find('span')
.should('have.text', 'Saved - not published')
cy.get('md-editor-publish-button')
.find('gn-ui-button')
.should('have.attr', 'ng-reflect-message', 'Publish this dataset')
})
})

describe('undo', () => {
it('should restore the record and refresh the interface', () => {
// First create a record and its draft
cy.get('[data-cy="create-record"]').click()
cy.url().should('include', '/create')
// Edit an existing record and create a draft
cy.get('[data-cy="resultItemTitle"]').first().click()
cy.url().should('include', '/edit')
cy.get('gn-ui-form-field[ng-reflect-model=abstract] textarea')
.as('abstractField')
.focus()
Expand Down Expand Up @@ -242,7 +190,7 @@ describe('record-actions', () => {
.first()
.find('textarea')
.invoke('val')
.should('eq', 'Accroches vélos MEL (Copy)')
.should('include', 'Copy of record Accroches vélos MEL')

// delete the new record
cy.visit('/catalog/search')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
RecordsApiService,
} from '@geonetwork-ui/data-access/gn4'
import { barbieUserFixture } from '@geonetwork-ui/common/fixtures'
import { OverlayRef } from '@angular/cdk/overlay'

class EditorFacadeMock {
changedSinceSave$ = new BehaviorSubject(false)
Expand Down Expand Up @@ -44,6 +43,7 @@ class EditorFacadeMock {
extras: { ownerInfo: '1|John|Doe' },
})
)
isPublished$ = new BehaviorSubject(true)
}

const user = barbieUserFixture()
Expand Down Expand Up @@ -135,6 +135,16 @@ describe('PublishButtonComponent', () => {
)
})
})
describe('has never been published', () => {
beforeEach(() => {
facade.isPublished$.next(false)
})
it('should return "hasChanges" when has never been published', async () => {
await expect(firstValueFrom(component.status$)).resolves.toBe(
'hasChanges'
)
})
})
describe('up to date', () => {
it('should return "upToDate" when not saving and not changed', async () => {
await expect(firstValueFrom(component.status$)).resolves.toBe(
Expand Down
Loading

0 comments on commit 2804667

Please sign in to comment.