/*
 * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
 *
 * SPDX-License-Identifier: AGPL-3.0-only
 */
import { buildStateFromServerDto } from './build-state-from-set-note-data-from-server'
import * as buildStateFromUpdatedMarkdownContentModule from '../build-state-from-updated-markdown-content'
import { Mock } from 'ts-mockery'
import type { NoteDetails } from '../types/note-details'
import { NoteTextDirection, NoteType } from '../types/note-details'
import { DateTime } from 'luxon'
import { initialSlideOptions } from '../initial-state'
import type { Note } from '../../../api/notes/types'

describe('build state from set note data from server', () => {
  const buildStateFromUpdatedMarkdownContentMock = jest.spyOn(
    buildStateFromUpdatedMarkdownContentModule,
    'buildStateFromUpdatedMarkdownContent'
  )
  const mockedNoteDetails = Mock.of<NoteDetails>()

  beforeAll(() => {
    buildStateFromUpdatedMarkdownContentMock.mockImplementation(() => mockedNoteDetails)
  })

  afterAll(() => {
    buildStateFromUpdatedMarkdownContentMock.mockReset()
  })

  it('builds a new state from the given note dto', () => {
    const noteDto: Note = {
      content: 'line1\nline2',
      metadata: {
        primaryAddress: 'alias',
        version: 5678,
        aliases: [
          {
            noteId: 'id',
            primaryAlias: true,
            name: 'alias'
          }
        ],
        id: 'id',
        createdAt: '2012-05-25T09:08:34.123',
        description: 'description',
        editedBy: ['editedBy'],
        permissions: {
          owner: 'username',
          sharedToGroups: [
            {
              canEdit: true,
              groupName: 'groupName'
            }
          ],
          sharedToUsers: [
            {
              canEdit: true,
              username: 'shareusername'
            }
          ]
        },
        viewCount: 987,
        tags: ['tag'],
        title: 'title',
        updatedAt: '2020-05-25T09:08:34.123',
        updateUsername: 'updateusername'
      },
      editedByAtPosition: [
        {
          endPos: 5,
          createdAt: 'createdAt',
          startPos: 9,
          updatedAt: 'updatedAt',
          username: 'userName'
        }
      ]
    }

    const convertedNoteDetails: NoteDetails = {
      frontmatter: {
        title: '',
        description: '',
        tags: [],
        deprecatedTagsSyntax: false,
        robots: '',
        lang: 'en',
        dir: NoteTextDirection.LTR,
        newlinesAreBreaks: true,
        GA: '',
        disqus: '',
        type: NoteType.DOCUMENT,
        opengraph: {},
        slideOptions: {
          transition: 'zoom',
          autoSlide: 0,
          autoSlideStoppable: true,
          backgroundTransition: 'fade',
          slideNumber: false
        }
      },
      frontmatterRendererInfo: {
        frontmatterInvalid: false,
        deprecatedSyntax: false,
        lineOffset: 0,
        slideOptions: initialSlideOptions
      },
      title: 'title',
      selection: { from: 0 },
      markdownContent: {
        plain: 'line1\nline2',
        lines: ['line1', 'line2'],
        lineStartIndexes: [0, 6]
      },
      firstHeading: '',
      rawFrontmatter: '',
      id: 'id',
      createdAt: DateTime.fromISO('2012-05-25T09:08:34.123'),
      updatedAt: DateTime.fromISO('2020-05-25T09:08:34.123'),
      updateUsername: 'updateusername',
      viewCount: 987,
      aliases: [
        {
          name: 'alias',
          noteId: 'id',
          primaryAlias: true
        }
      ],
      primaryAddress: 'alias',
      version: 5678,
      editedBy: ['editedBy'],
      permissions: {
        owner: 'username',
        sharedToGroups: [
          {
            canEdit: true,
            groupName: 'groupName'
          }
        ],
        sharedToUsers: [
          {
            canEdit: true,
            username: 'shareusername'
          }
        ]
      }
    }

    const result = buildStateFromServerDto(noteDto)
    expect(result).toEqual(mockedNoteDetails)
    expect(buildStateFromUpdatedMarkdownContentMock).toHaveBeenCalledWith(convertedNoteDetails, 'line1\nline2')
  })
})
