Merge branch 'v9/contrib' into temp-11381
This commit is contained in:
5
tests/.editorconfig
Normal file
5
tests/.editorconfig
Normal file
@@ -0,0 +1,5 @@
|
||||
root = false
|
||||
|
||||
[*.cs]
|
||||
csharp_style_var_when_type_is_apparent = true:none
|
||||
csharp_style_var_elsewhere = true:none
|
||||
@@ -343,17 +343,11 @@ context('Content', () => {
|
||||
// Rollback
|
||||
cy.get('.umb-box-header :button').click();
|
||||
|
||||
cy.get('.umb-box-content > div > .input-block-level')
|
||||
.find('option[label*=' + new Date().getDate() + ']')
|
||||
.then(elements => {
|
||||
const option = elements[elements.length - 1].getAttribute('value');
|
||||
cy.get('.umb-box-content > div > .input-block-level')
|
||||
.select(option);
|
||||
});
|
||||
cy.get('.-selectable.cursor-pointer:first').click();
|
||||
|
||||
cy.get('.umb-editor-footer-content__right-side > [button-style="success"] > .umb-button > .btn-success').click();
|
||||
|
||||
cy.reload();
|
||||
refreshContentTree();
|
||||
|
||||
// Assert
|
||||
cy.get('.history').find('.umb-badge').contains('Save').should('be.visible');
|
||||
@@ -759,7 +753,8 @@ context('Content', () => {
|
||||
// Click macro
|
||||
cy.get(':nth-child(4) > .umb-card-grid-item > :nth-child(1)').click();
|
||||
// Select the macro
|
||||
cy.get('.umb-card-grid-item').contains(macroName).click();
|
||||
cy.get(`.umb-card-grid-item[title='${macroName}']`).click('bottom');
|
||||
|
||||
|
||||
// Save and publish
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
/// <reference types="Cypress" />
|
||||
import {
|
||||
DocumentTypeBuilder,
|
||||
ContentBuilder
|
||||
} from 'umbraco-cypress-testhelpers';
|
||||
|
||||
context('Routing', () => {
|
||||
|
||||
let swedishLanguageId = 0;
|
||||
const swedishCulture = "sv";
|
||||
const danishCulture = "da"
|
||||
const nodeName = "Root";
|
||||
const childNodeName = "Child";
|
||||
const grandChildNodeName = "Grandchild";
|
||||
const rootDocTypeName = "Test document type";
|
||||
|
||||
function refreshContentTree() {
|
||||
// Refresh to update the tree
|
||||
cy.get('li .umb-tree-root:contains("Content")').should("be.visible").rightclick();
|
||||
cy.umbracoContextMenuAction("action-refreshNode").click();
|
||||
// We have to wait in case the execution is slow, otherwise we'll try and click the item before it appears in the UI
|
||||
cy.get('.umb-tree-item__inner').should('exist', {timeout: 10000});
|
||||
}
|
||||
|
||||
function saveNewLanguages() {
|
||||
// Save Danish
|
||||
const url = "/umbraco/backoffice/umbracoapi/language/SaveLanguage";
|
||||
const danishRequestBody = {
|
||||
culture: danishCulture
|
||||
}
|
||||
|
||||
cy.umbracoApiRequest(url, "POST", danishRequestBody);
|
||||
|
||||
// Save Swedish
|
||||
const swedishRequestBody = {
|
||||
culture: swedishCulture
|
||||
}
|
||||
cy.umbracoApiRequest(url, "POST", swedishRequestBody).then((responseBody) => {
|
||||
swedishLanguageId = responseBody["id"];
|
||||
});
|
||||
}
|
||||
|
||||
function configureDomain(id, name, lang) {
|
||||
//Save domain for child node
|
||||
const url = "/umbraco/backoffice/umbracoapi/content/PostSaveLanguageAndDomains"
|
||||
const body = {
|
||||
nodeId : id,
|
||||
domains : [
|
||||
{
|
||||
name : name,
|
||||
lang : lang
|
||||
}],
|
||||
language : 0
|
||||
}
|
||||
cy.umbracoApiRequest(url, 'POST', body);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
|
||||
// Ensure cleaned before tests run
|
||||
cy.deleteAllContent();
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(rootDocTypeName);
|
||||
cy.umbracoEnsureLanguageNotExists(danishCulture);
|
||||
cy.umbracoEnsureLanguageNotExists(swedishCulture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Cleanup after tests
|
||||
cy.deleteAllContent();
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(rootDocTypeName);
|
||||
cy.umbracoEnsureLanguageNotExists(danishCulture);
|
||||
cy.umbracoEnsureLanguageNotExists(swedishCulture);
|
||||
})
|
||||
|
||||
it('Root node published in language A, Child node published in language A', () => {
|
||||
|
||||
const rootDocType = new DocumentTypeBuilder()
|
||||
.withName(rootDocTypeName)
|
||||
.withAllowAsRoot(true)
|
||||
.withAllowCultureVariation(true)
|
||||
.build();
|
||||
|
||||
saveNewLanguages();
|
||||
|
||||
cy.saveDocumentType(rootDocType).then((generatedRootDocType) => {
|
||||
const rootContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("publishNew")
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(nodeName)
|
||||
.withSave(true)
|
||||
.withPublish(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(rootContentNode).then((generatedRootContent) => {
|
||||
const childContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("saveNew")
|
||||
.withParent(generatedRootContent["id"])
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(childNodeName)
|
||||
.withSave(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(childContentNode);
|
||||
});
|
||||
});
|
||||
|
||||
// Refresh to update the tree
|
||||
refreshContentTree();
|
||||
|
||||
cy.umbracoTreeItem("content", [nodeName, childNodeName]).click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
// Pop-up with what cultures you want to publish shows, click it
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').last().click();
|
||||
|
||||
// Assert
|
||||
cy.get('.alert-success').should('exist');
|
||||
});
|
||||
|
||||
|
||||
it('Root node published in language A, Child node published in language B', () => {
|
||||
|
||||
const rootDocType = new DocumentTypeBuilder()
|
||||
.withName(rootDocTypeName)
|
||||
.withAllowAsRoot(true)
|
||||
.withAllowCultureVariation(true)
|
||||
.build();
|
||||
|
||||
saveNewLanguages();
|
||||
|
||||
cy.saveDocumentType(rootDocType).then((generatedRootDocType) => {
|
||||
const rootContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("publishNew")
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(nodeName)
|
||||
.withSave(true)
|
||||
.withPublish(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(rootContentNode).then((generatedRootContent) => {
|
||||
const childContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("saveNew")
|
||||
.withParent(generatedRootContent["id"])
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(childNodeName)
|
||||
.withSave(true)
|
||||
.done()
|
||||
.addVariant()
|
||||
.withCulture(swedishCulture)
|
||||
.withName("Bärn")
|
||||
.withSave(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(childContentNode);
|
||||
});
|
||||
});
|
||||
|
||||
// Refresh to update the tree
|
||||
refreshContentTree();
|
||||
|
||||
cy.umbracoTreeItem("content", [nodeName, childNodeName]).click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
// Pop-up with what cultures you want to publish shows, click it
|
||||
cy.get('.umb-list').should('be.visible');
|
||||
cy.get('.checkbox').last().click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').last().click();
|
||||
|
||||
// Assert
|
||||
cy.get('.alert-success').should('have.length', 2);
|
||||
cy.get('.alert-warning').should('exist');
|
||||
});
|
||||
|
||||
it('Root node published in language A, Child node published in language A + B, Grandchild published in A + B', () => {
|
||||
|
||||
const rootDocType = new DocumentTypeBuilder()
|
||||
.withName(rootDocTypeName)
|
||||
.withAllowAsRoot(true)
|
||||
.withAllowCultureVariation(true)
|
||||
.build();
|
||||
|
||||
saveNewLanguages();
|
||||
|
||||
cy.saveDocumentType(rootDocType).then((generatedRootDocType) => {
|
||||
const rootContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("publishNew")
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(nodeName)
|
||||
.withSave(true)
|
||||
.withPublish(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(rootContentNode).then((generatedRootContent) => {
|
||||
|
||||
configureDomain(generatedRootContent["id"], "/en", 1);
|
||||
const childContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("saveNew")
|
||||
.withParent(generatedRootContent["id"])
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(childNodeName)
|
||||
.withSave(true)
|
||||
.done()
|
||||
.addVariant()
|
||||
.withCulture(swedishCulture)
|
||||
.withName("Barn")
|
||||
.withSave(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(childContentNode).then((generatedChildContent) => {
|
||||
|
||||
configureDomain(generatedChildContent["id"], "/sv", swedishLanguageId);
|
||||
const grandChildContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("saveNew")
|
||||
.withParent(generatedChildContent["id"])
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(grandChildNodeName)
|
||||
.withSave(true)
|
||||
.done()
|
||||
.addVariant()
|
||||
.withCulture(swedishCulture)
|
||||
.withName("Barnbarn")
|
||||
.withSave(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(grandChildContentNode);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Refresh to update the tree
|
||||
refreshContentTree();
|
||||
|
||||
// Publish Child
|
||||
cy.umbracoTreeItem("content", [nodeName, childNodeName]).click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
//Pop-up with what cultures you want to publish shows, click it
|
||||
cy.get('.umb-list').should('be.visible');
|
||||
cy.get('.checkbox').last().click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').last().click();
|
||||
|
||||
// Publish Grandchild
|
||||
cy.umbracoTreeItem("content", [nodeName, childNodeName, grandChildNodeName]).click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
// Pop-up with what cultures you want to publish shows, click it
|
||||
cy.get('.umb-list').should('be.visible');
|
||||
cy.get('.checkbox').last().click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').last().click();
|
||||
|
||||
// Assert
|
||||
cy.get('.alert-success').should('have.length', 2);
|
||||
cy.get('.alert-warning').should('not.exist');
|
||||
});
|
||||
|
||||
it('Root node published in language A, Child node published in language A + B, Grandchild published in A + B + C', () => {
|
||||
|
||||
const rootDocType = new DocumentTypeBuilder()
|
||||
.withName(rootDocTypeName)
|
||||
.withAllowAsRoot(true)
|
||||
.withAllowCultureVariation(true)
|
||||
.build();
|
||||
|
||||
saveNewLanguages();
|
||||
|
||||
cy.saveDocumentType(rootDocType).then((generatedRootDocType) => {
|
||||
const rootContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("publishNew")
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(nodeName)
|
||||
.withSave(true)
|
||||
.withPublish(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(rootContentNode).then((generatedRootContent) => {
|
||||
|
||||
configureDomain(generatedRootContent["id"], "/en", 1);
|
||||
const childContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("saveNew")
|
||||
.withParent(generatedRootContent["id"])
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(childNodeName)
|
||||
.withSave(true)
|
||||
.done()
|
||||
.addVariant()
|
||||
.withCulture(swedishCulture)
|
||||
.withName("Barn")
|
||||
.withSave(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(childContentNode).then((generatedChildContent) => {
|
||||
|
||||
configureDomain(generatedChildContent["id"], "/sv", swedishLanguageId);
|
||||
const grandChildContentNode = new ContentBuilder()
|
||||
.withContentTypeAlias(generatedRootDocType["alias"])
|
||||
.withAction("saveNew")
|
||||
.withParent(generatedChildContent["id"])
|
||||
.addVariant()
|
||||
.withCulture('en-US')
|
||||
.withName(grandChildNodeName)
|
||||
.withSave(true)
|
||||
.done()
|
||||
.addVariant()
|
||||
.withCulture(swedishCulture)
|
||||
.withName("Barnbarn")
|
||||
.withSave(true)
|
||||
.done()
|
||||
.addVariant()
|
||||
.withCulture(danishCulture)
|
||||
.withName("Barnebarn")
|
||||
.withSave(true)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
cy.saveContent(grandChildContentNode);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Refresh to update the tree
|
||||
refreshContentTree();
|
||||
|
||||
// Publish Child
|
||||
cy.umbracoTreeItem("content", [nodeName, childNodeName]).click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
// Pop-up with what cultures you want to publish shows, click it
|
||||
cy.get('.umb-list').should('be.visible');
|
||||
cy.get('.checkbox').last().click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').last().click();
|
||||
|
||||
// Publish Grandchild
|
||||
cy.umbracoTreeItem("content", [nodeName, childNodeName, grandChildNodeName]).click();
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
// Pop-up with what cultures you want to publish shows, click it
|
||||
cy.get('.umb-list').should('be.visible');
|
||||
cy.get('.checkbox').click({multiple : true});
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').last().click();
|
||||
|
||||
// Assert
|
||||
cy.get('.alert-success').should('exist');
|
||||
cy.get('.alert-warning').should('exist');
|
||||
});
|
||||
});
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
context('DataTypes', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'), false);
|
||||
});
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
|
||||
});
|
||||
|
||||
it('Tests Approved Colors', () => {
|
||||
cy.deleteAllContent();
|
||||
@@ -26,6 +26,12 @@ context('DataTypes', () => {
|
||||
|
||||
//umbracoMakeDocTypeWithDataTypeAndContent(name, alias, pickerDataType);
|
||||
cy.umbracoCreateDocTypeWithContent(name, alias, pickerDataType);
|
||||
//Editing template with some content
|
||||
cy.editTemplate(name, '@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ApprovedColourTest>' +
|
||||
'\n@{' +
|
||||
'\n Layout = null;' +
|
||||
'\n}' +
|
||||
'\n<p style="color:@Model.UmbracoTest">Lorem ipsum dolor sit amet</p>');
|
||||
|
||||
// Act
|
||||
// Enter content
|
||||
@@ -36,22 +42,19 @@ context('DataTypes', () => {
|
||||
//Save
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
//Editing template with some content
|
||||
cy.editTemplate(name, '@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ApprovedColourTest>' +
|
||||
'\n@{' +
|
||||
'\n Layout = null;' +
|
||||
'\n}' +
|
||||
'\n<p style="color:@Model.UmbracoTest">Lorem ipsum dolor sit amet</p>');
|
||||
|
||||
//Assert
|
||||
const expected = `<p style="color:000000" > Lorem ipsum dolor sit amet </p>`;
|
||||
cy.umbracoVerifyRenderedViewContent('/', expected, true).should('be.true');
|
||||
cy.get('.umb-button__overlay').should('not.be.visible');
|
||||
|
||||
//Pick another colour to verify both work
|
||||
cy.get('.btn-FF0000').click();
|
||||
//Save
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').click();
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.umbracoButtonByLabelKey('buttons_saveAndPublish').should('be.visible');
|
||||
cy.get('.umb-button__overlay').should('not.be.visible');
|
||||
//Assert
|
||||
const expected2 = '<p style="color:FF0000">Lorem ipsum dolor sit amet</p>';
|
||||
cy.umbracoVerifyRenderedViewContent('/', expected2, true).should('be.true');
|
||||
@@ -100,6 +103,7 @@ context('DataTypes', () => {
|
||||
cy.get('.property-error').should('be.visible');
|
||||
|
||||
// Clean
|
||||
cy.umbracoEnsureTemplateNameNotExists(name);
|
||||
cy.umbracoEnsureDataTypeNameNotExists(name);
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(name);
|
||||
})
|
||||
|
||||
@@ -24,7 +24,7 @@ context('System Information', () => {
|
||||
cy.contains('Current Culture').parent().should('contain', 'en-US');
|
||||
cy.contains('Current UI Culture').parent().should('contain', 'en-US');
|
||||
});
|
||||
|
||||
|
||||
it('Checks language displays correctly after switching', () => {
|
||||
|
||||
//Navigate to edit user and change language
|
||||
@@ -32,10 +32,8 @@ context('System Information', () => {
|
||||
cy.get('[alias="editUser"]').click();
|
||||
cy.get('[name="culture"]').select('string:da-DK', { force: true});
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click({force: true});
|
||||
//Refresh site to display new language
|
||||
cy.reload();
|
||||
cy.get('.umb-tour-step', { timeout: 60000 }).should('be.visible'); // We now due to the api calls this will be shown, but slow computers can take a while
|
||||
cy.get('.umb-tour-step__close').click();
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
|
||||
openSystemInformation();
|
||||
//Assert
|
||||
cy.contains('Current Culture').parent().should('contain', 'da-DK');
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
context('Languages', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'), false);
|
||||
});
|
||||
|
||||
it('Creates language', () => {
|
||||
// Setup
|
||||
const language = 'Danish';
|
||||
const culture = 'da';
|
||||
cy.umbracoEnsureLanguageCultureNotExists(culture);
|
||||
cy.umbracoSection('settings');
|
||||
|
||||
// Enter language tree and create new language
|
||||
cy.umbracoTreeItem('settings', ['Languages']).click();
|
||||
cy.umbracoButtonByLabelKey('languages_addLanguage').click();
|
||||
cy.get('select[name="newLang"]').select(language);
|
||||
|
||||
// Save and assert success
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click();
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
|
||||
// Cleanup
|
||||
cy.umbracoEnsureLanguageCultureNotExists(culture);
|
||||
});
|
||||
|
||||
it('Deletes language', () => {
|
||||
// Setup
|
||||
const language1 = 'da';
|
||||
const language2 = 'en-GB';
|
||||
cy.umbracoEnsureLanguageCultureNotExists(language1);
|
||||
cy.umbracoEnsureLanguageCultureNotExists(language2);
|
||||
|
||||
cy.umbracoCreateLanguage(language1, true, '1');
|
||||
cy.umbracoCreateLanguage(language2, true, '1');
|
||||
//Enter settings section and wait for everything to load
|
||||
cy.umbracoSection('settings');
|
||||
cy.get('.umb-box-content').should('be.visible');
|
||||
cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
|
||||
|
||||
// Enter language tree and select the language we just created
|
||||
cy.umbracoTreeItem('settings', ['Languages']).click();
|
||||
|
||||
// Assert there are 3 languages
|
||||
cy.get('tbody > tr').should('have.length', 3);
|
||||
|
||||
// Delete UK Language
|
||||
cy.get('umb-button[label-key="general_delete"]').last().click();
|
||||
cy.umbracoButtonByLabelKey('contentTypeEditor_yesDelete').click();
|
||||
|
||||
// Assert there is only 2 languages
|
||||
cy.get('tbody > tr').should('have.length', 2);
|
||||
|
||||
// Cleanup
|
||||
cy.umbracoEnsureLanguageCultureNotExists(language1);
|
||||
cy.umbracoEnsureLanguageCultureNotExists(language2);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -16,7 +16,7 @@ context('Media Types', () => {
|
||||
cy.umbracoTreeItem("settings", ["Media Types"]).rightclick();
|
||||
|
||||
cy.umbracoContextMenuAction("action-create").click();
|
||||
cy.get('.menu-label').first().click(); // TODO: Fucked we cant use something like cy.umbracoContextMenuAction("action-mediaType").click();
|
||||
cy.get('.menu-label localize[key="content_mediatype"]').click();
|
||||
|
||||
|
||||
//Type name
|
||||
|
||||
@@ -29,7 +29,7 @@ context('Partial View Macro Files', () => {
|
||||
|
||||
openPartialViewMacroCreatePanel();
|
||||
|
||||
cy.get('.menu-label').first().click(); // TODO: Fucked we cant use something like cy.umbracoContextMenuAction("action-label").click();
|
||||
cy.get('.menu-label localize[key="create_newPartialViewMacro"]').click();
|
||||
|
||||
//Type name
|
||||
cy.umbracoEditorHeaderName(name);
|
||||
|
||||
@@ -26,7 +26,7 @@ context('Partial Views', () => {
|
||||
openPartialViewsCreatePanel();
|
||||
|
||||
cy.umbracoContextMenuAction("action-create").click();
|
||||
cy.get('.menu-label').first().click(); // TODO: Fucked we cant use something like cy.umbracoContextMenuAction("action-mediaType").click();
|
||||
cy.get('.menu-label localize[key="create_newEmptyPartialView"]').click();
|
||||
|
||||
//Type name
|
||||
cy.umbracoEditorHeaderName(name);
|
||||
@@ -73,7 +73,7 @@ context('Partial Views', () => {
|
||||
openPartialViewsCreatePanel();
|
||||
|
||||
cy.umbracoContextMenuAction("action-create").click();
|
||||
cy.get('.menu-label').first().click();
|
||||
cy.get('.menu-label localize[key="create_newEmptyPartialView"]').click();
|
||||
|
||||
// The test would fail intermittently, most likely because the editor didn't have time to load
|
||||
// This should ensure that the editor is loaded and the test should no longer fail unexpectedly.
|
||||
|
||||
@@ -23,7 +23,10 @@ context('Scripts', () => {
|
||||
cy.umbracoTreeItem("settings", ["Scripts"]).rightclick();
|
||||
|
||||
cy.umbracoContextMenuAction("action-create").click();
|
||||
cy.get('.menu-label').first().click(); // TODO: Fucked we cant use something like cy.umbracoContextMenuAction("action-mediaType").click();
|
||||
cy.get('.menu-label localize[key="create_newJavascriptFile"]').click();
|
||||
//We have to wait here till everything is loaded, or worker will throw error
|
||||
cy.intercept('/umbraco/lib/ace-builds/src-min-noconflict/worker-javascript.js').as('aceWorker');
|
||||
cy.wait('@aceWorker');
|
||||
|
||||
//Type name
|
||||
cy.umbracoEditorHeaderName(name);
|
||||
@@ -33,6 +36,8 @@ context('Scripts', () => {
|
||||
|
||||
//Assert
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
|
||||
|
||||
cy.umbracoScriptExists(fileName).should('be.true');
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
/// <reference types="Cypress" />
|
||||
context('Stylesheets', () => {
|
||||
|
||||
const name = "TestStylesheet";
|
||||
const fileName = name + ".css";
|
||||
|
||||
beforeEach(() => {
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
|
||||
|
||||
cy.umbracoEnsureStylesheetNameNotExists(fileName);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Clean up, this ensures that even if tests break we clean up
|
||||
cy.umbracoEnsureStylesheetNameNotExists(fileName);
|
||||
});
|
||||
|
||||
it('Create new style sheet file', () => {
|
||||
const name = "TestStylesheet";
|
||||
const fileName = name + ".css";
|
||||
|
||||
cy.umbracoEnsureStylesheetNameNotExists(fileName);
|
||||
|
||||
cy.umbracoSection('settings');
|
||||
cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
|
||||
@@ -17,19 +23,52 @@ context('Stylesheets', () => {
|
||||
cy.umbracoTreeItem("settings", ["Stylesheets"]).rightclick();
|
||||
|
||||
cy.umbracoContextMenuAction("action-create").click();
|
||||
cy.get('.menu-label').first().click(); // TODO: Fucked we cant use something like cy.umbracoContextMenuAction("action-mediaType").click();
|
||||
cy.get('.menu-label').first().click(); // TODO: Would be better to use something like cy.umbracoContextMenuAction("action-mediaType").click();
|
||||
// We have to wait here till everything is loaded, or worker will throw error
|
||||
cy.intercept('/umbraco/lib/ace-builds/src-min-noconflict/worker-css.js').as('aceWorker');
|
||||
cy.wait('@aceWorker');
|
||||
|
||||
//Type name
|
||||
// Type name
|
||||
cy.umbracoEditorHeaderName(name);
|
||||
|
||||
//Save
|
||||
// Save
|
||||
cy.get('.btn-success').click();
|
||||
|
||||
//Assert
|
||||
// Assert
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
|
||||
//Clean up
|
||||
cy.umbracoEnsureStylesheetNameNotExists(fileName);
|
||||
});
|
||||
|
||||
it('Deletes a stylesheet', () => {
|
||||
|
||||
var stylesheetData = {
|
||||
"virtualPath": "/css/",
|
||||
"path": null,
|
||||
"name": name,
|
||||
"content": "",
|
||||
"fileType": "stylesheets",
|
||||
"snippet": null,
|
||||
"id": "0",
|
||||
"notifications": []
|
||||
}
|
||||
|
||||
let url = '/umbraco/backoffice/umbracoapi/codefile/PostSave'
|
||||
cy.umbracoApiRequest(url, 'POST', stylesheetData);
|
||||
|
||||
// Navigate to Settings section
|
||||
cy.umbracoSection('settings');
|
||||
cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
|
||||
|
||||
// Open stylesheet tree
|
||||
cy.get('[data-element="tree-item-stylesheets"] > .umb-tree-item__inner > .umb-tree-item__arrow').click();
|
||||
|
||||
// Delete stylesheet
|
||||
cy.get('.umb-tree-item__inner > .umb-tree-item__label').contains(name).rightclick();
|
||||
cy.get('.umb-action-link').click();
|
||||
cy.get('[ng-if="showConfirm"]').click();
|
||||
|
||||
// Assert
|
||||
cy.get('.umb-tree-item__inner > .umb-tree-item__label').contains(name).should('not.exist');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,7 +68,9 @@ context('Templates', () => {
|
||||
// Open partial view
|
||||
cy.umbracoTreeItem("settings", ["Templates", name]).click();
|
||||
// Edit
|
||||
cy.get('.ace_text-input').type(edit, {force:true} );
|
||||
cy.get('.ace_content').type(edit);
|
||||
cy.get('.ace_content').contains(edit).should('be.visible');
|
||||
cy.get('.btn-success').should('be.visible')
|
||||
|
||||
// Navigate away
|
||||
cy.umbracoSection('content');
|
||||
@@ -101,7 +103,9 @@ context('Templates', () => {
|
||||
// Open partial view
|
||||
cy.umbracoTreeItem("settings", ["Templates", name]).click();
|
||||
// Edit
|
||||
cy.get('.ace_text-input').type(edit, {force:true} );
|
||||
cy.get('.ace_content').type(edit);
|
||||
cy.get('.ace_content').contains(edit).should('be.visible');
|
||||
cy.get('.btn-success').should('be.visible')
|
||||
|
||||
// Navigate away
|
||||
cy.umbracoSection('content');
|
||||
@@ -136,7 +140,7 @@ context('Templates', () => {
|
||||
// Insert macro
|
||||
cy.umbracoButtonByLabelKey('general_insert').click();
|
||||
cy.get('.umb-insert-code-box__title').contains('Macro').click();
|
||||
cy.get('.umb-card-grid-item').contains(name).click();
|
||||
cy.get(`.umb-card-grid-item[title='${name}']`).click('bottom');
|
||||
|
||||
// Assert
|
||||
cy.get('.ace_content').contains('@await Umbraco.RenderMacroAsync("' + name + '")').should('exist');
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
/// <reference types="Cypress" />
|
||||
import {
|
||||
DocumentTypeBuilder,
|
||||
import {
|
||||
DocumentTypeBuilder,
|
||||
AliasHelper
|
||||
} from 'umbraco-cypress-testhelpers';
|
||||
|
||||
|
||||
const tabsDocTypeName = 'Tabs Test Document';
|
||||
const tabsDocTypeAlias = AliasHelper.toAlias(tabsDocTypeName);
|
||||
|
||||
|
||||
context('Tabs', () => {
|
||||
|
||||
|
||||
beforeEach(() => {
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'), false);
|
||||
});
|
||||
|
||||
|
||||
afterEach(() => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName)
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
cy.umbracoEnsureTemplateNameNotExists(tabsDocTypeName);
|
||||
});
|
||||
|
||||
|
||||
function OpenDocTypeFolder(){
|
||||
cy.umbracoSection('settings');
|
||||
// We have to wait in case the execution is slow, otherwise we'll try and click the item before it appears in the UI
|
||||
cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
|
||||
cy.get('.umb-tree-item__inner > .umb-tree-item__arrow').eq(0).click();
|
||||
cy.get('.umb-tree-item__inner > .umb-tree-item__label').contains(tabsDocTypeName).click();
|
||||
cy.umbracoTreeItem('settings', ["Document Types", tabsDocTypeName]).click();
|
||||
}
|
||||
|
||||
|
||||
function CreateDocWithTabAndNavigate(){
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -44,8 +45,8 @@ import {
|
||||
cy.saveDocumentType(tabsDocType);
|
||||
OpenDocTypeFolder();
|
||||
}
|
||||
|
||||
it('Create tab', () => {
|
||||
|
||||
it('Create tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
cy.deleteAllContent();
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -72,13 +73,13 @@ import {
|
||||
cy.get('[aria-hidden="false"] > .umb-box-content > .umb-group-builder__group-add-property').click();
|
||||
cy.get('.editor-label').type('property name');
|
||||
cy.get('[data-element="editor-add"]').click();
|
||||
|
||||
|
||||
//Search for textstring
|
||||
cy.get('#datatype-search').type('Textstring');
|
||||
|
||||
|
||||
// Choose first item
|
||||
cy.get('[title="Textstring"]').closest("li").click();
|
||||
|
||||
|
||||
// Save property
|
||||
cy.get('.btn-success').last().click();
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click();
|
||||
@@ -87,21 +88,19 @@ import {
|
||||
cy.get('[title="tab1"]').should('be.visible');
|
||||
cy.get('[title="tab2"]').should('be.visible');
|
||||
});
|
||||
|
||||
it('Delete tabs', () => {
|
||||
|
||||
it('Delete tabs', () => {
|
||||
CreateDocWithTabAndNavigate();
|
||||
//Check if tab is there, else if it wasnt created, this test would always pass
|
||||
cy.get('[title="aTab 1"]').should('be.visible');
|
||||
//Delete a tab
|
||||
cy.get('.btn-reset > .icon-trash').click();
|
||||
cy.get('.btn-reset > [icon="icon-trash"]').first().click();
|
||||
cy.get('.umb-button > .btn').last().click();
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click();
|
||||
//Assert
|
||||
cy.get('[title="aTab 1"]').should('not.exist');
|
||||
//Clean
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
});
|
||||
|
||||
|
||||
it('Delete property in tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -132,7 +131,7 @@ import {
|
||||
cy.get('[title=urlPicker]').should('be.visible');
|
||||
cy.get('[title=picker]').should('not.exist');
|
||||
});
|
||||
|
||||
|
||||
it('Delete group in tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -159,7 +158,7 @@ import {
|
||||
cy.saveDocumentType(tabsDocType);
|
||||
OpenDocTypeFolder();
|
||||
//Delete group
|
||||
cy.get('.umb-group-builder__group-remove > .icon-trash').eq(1).click();
|
||||
cy.get('.umb-group-builder__group-remove > [icon="icon-trash"]').eq(1).click();
|
||||
cy.umbracoButtonByLabelKey('actions_delete').click();
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click()
|
||||
//Assert
|
||||
@@ -167,7 +166,7 @@ import {
|
||||
cy.get('[title=picker]').should('be.visible');
|
||||
cy.get('[title=urlPicker]').should('not.exist');
|
||||
});
|
||||
|
||||
|
||||
it('Reorders tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -219,7 +218,7 @@ import {
|
||||
cy.get('.umb-group-builder__group-title-input').eq(1).invoke('attr', 'title').should('eq', 'aTab 3')
|
||||
cy.get('.umb-group-builder__group-title-input').eq(2).invoke('attr', 'title').should('eq', 'aTab 1')
|
||||
});
|
||||
|
||||
|
||||
it('Reorders groups in a tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -249,7 +248,7 @@ import {
|
||||
OpenDocTypeFolder();
|
||||
cy.get('[alias="reorder"]').click();
|
||||
cy.get('.umb-property-editor-tiny').eq(2).type('1');
|
||||
|
||||
|
||||
cy.get('[alias="reorder"]').click();
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click();
|
||||
//Assert
|
||||
@@ -257,7 +256,7 @@ import {
|
||||
cy.get('.umb-group-builder__group-title-input').eq(2)
|
||||
.invoke('attr', 'title').should('eq', 'aTab 1/aTab group 2');
|
||||
});
|
||||
|
||||
|
||||
it('Reorders properties in a tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -286,12 +285,12 @@ import {
|
||||
cy.get('[alias="reorder"]').click();
|
||||
cy.get('.umb-group-builder__group-sort-value').first().type('2');
|
||||
cy.get('[alias="reorder"]').click();
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click();
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click();
|
||||
//Assert
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.get('.umb-locked-field__input').last().invoke('attr', 'title').should('eq', 'urlPicker');
|
||||
});
|
||||
|
||||
|
||||
it('Tab name cannot be empty', () => {
|
||||
CreateDocWithTabAndNavigate();
|
||||
cy.get('.umb-group-builder__group-title-input').first().clear();
|
||||
@@ -299,7 +298,7 @@ import {
|
||||
//Assert
|
||||
cy.umbracoErrorNotification().should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Two tabs cannot have the same name', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -326,7 +325,7 @@ import {
|
||||
//Assert
|
||||
cy.umbracoErrorNotification().should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Group name cannot be empty', () => {
|
||||
CreateDocWithTabAndNavigate();
|
||||
cy.get('.clearfix > .-placeholder').click();
|
||||
@@ -334,7 +333,7 @@ import {
|
||||
//Assert
|
||||
cy.umbracoErrorNotification().should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Group name cannot have the same name', () => {
|
||||
CreateDocWithTabAndNavigate();
|
||||
cy.get('.clearfix > .-placeholder').click();
|
||||
@@ -343,7 +342,7 @@ import {
|
||||
//Assert
|
||||
cy.umbracoErrorNotification().should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Drag a group into another tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -394,7 +393,7 @@ import {
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.get('[title="aTab 1/aTab group 2"]').should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Drag and drop reorders a tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -446,7 +445,7 @@ import {
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.get('[title="aTab 2"]').should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Drags and drops a property in a tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -502,7 +501,7 @@ import {
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.get('[title="urlPickerTabTwo"]').should('be.visible');
|
||||
});
|
||||
|
||||
|
||||
it('Drags and drops a group and converts to tab', () => {
|
||||
cy.umbracoEnsureDocumentTypeNameNotExists(tabsDocTypeName);
|
||||
const tabsDocType = new DocumentTypeBuilder()
|
||||
@@ -549,4 +548,4 @@ import {
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.get('[title="tabGroup"]').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,40 @@
|
||||
/// <reference types="Cypress" />
|
||||
context('Users', () => {
|
||||
|
||||
const name = "Alice Bobson";
|
||||
const email = "alice-bobson@acceptancetest.umbraco";
|
||||
const startContentIds = [];
|
||||
const startMediaIds = [];
|
||||
const userGroups = ["admin"];
|
||||
|
||||
const userData =
|
||||
{
|
||||
"id": -1,
|
||||
"parentId": -1,
|
||||
"name": name,
|
||||
"username": email,
|
||||
"culture": "en-US",
|
||||
"email": email,
|
||||
"startContentIds": startContentIds,
|
||||
"startMediaIds": startMediaIds,
|
||||
"userGroups": userGroups,
|
||||
"message": ""
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
//Clean up
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
});
|
||||
|
||||
function createUser(){
|
||||
let url = '/umbraco/backoffice/umbracoapi/users/PostCreateUser';
|
||||
cy.umbracoApiRequest(url, 'POST', userData);
|
||||
}
|
||||
it('Create user', () => {
|
||||
const name = "Alice Bobson";
|
||||
const email = "alice-bobson@acceptancetest.umbraco";
|
||||
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
cy.umbracoSection('users');
|
||||
@@ -24,55 +51,16 @@ context('Users', () => {
|
||||
|
||||
cy.get('.umb-button > .btn > .umb-button__content').click();
|
||||
|
||||
|
||||
cy.umbracoButtonByLabelKey("user_goToProfile").should('be.visible');
|
||||
|
||||
//Clean up
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
|
||||
});
|
||||
|
||||
it('Update user', () => {
|
||||
// Set userdata
|
||||
const name = "Alice Bobson";
|
||||
const email = "alice-bobson@acceptancetest.umbraco";
|
||||
const startContentIds = [];
|
||||
const startMediaIds = [];
|
||||
const userGroups = ["admin"];
|
||||
|
||||
var userData =
|
||||
{
|
||||
"id": -1,
|
||||
"parentId": -1,
|
||||
"name": name,
|
||||
"username": email,
|
||||
"culture": "en-US",
|
||||
"email": email,
|
||||
"startContentIds": startContentIds,
|
||||
"startMediaIds": startMediaIds,
|
||||
"userGroups": userGroups,
|
||||
"message": ""
|
||||
};
|
||||
|
||||
// Ensure user doesn't exist
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
|
||||
// Create user through API
|
||||
cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/umbraco/backoffice/umbracoapi/users/PostCreateUser',
|
||||
followRedirect: true,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'X-UMB-XSRF-TOKEN': token.value,
|
||||
},
|
||||
body: userData,
|
||||
log: false,
|
||||
}).then((response) => {
|
||||
return;
|
||||
});
|
||||
});
|
||||
|
||||
//Create user through API
|
||||
createUser();
|
||||
|
||||
// Go to the user and edit their name
|
||||
cy.umbracoSection('users');
|
||||
@@ -82,50 +70,15 @@ context('Users', () => {
|
||||
|
||||
// assert save succeeds
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
})
|
||||
|
||||
it('Delete user', () => {
|
||||
// Set userdata
|
||||
const name = "Alice Bobson";
|
||||
const email = "alice-bobson@acceptancetest.umbraco";
|
||||
const startContentIds = [];
|
||||
const startMediaIds = [];
|
||||
const userGroups = ["admin"];
|
||||
|
||||
var userData =
|
||||
{
|
||||
"id": -1,
|
||||
"parentId": -1,
|
||||
"name": name,
|
||||
"username": email,
|
||||
"culture": "en-US",
|
||||
"email": email,
|
||||
"startContentIds": startContentIds,
|
||||
"startMediaIds": startMediaIds,
|
||||
"userGroups": userGroups,
|
||||
"message": ""
|
||||
};
|
||||
it('Delete user', () => {
|
||||
|
||||
// Ensure user doesn't exist
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
|
||||
// Create user through API
|
||||
cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/umbraco/backoffice/umbracoapi/users/PostCreateUser',
|
||||
followRedirect: true,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'X-UMB-XSRF-TOKEN': token.value,
|
||||
},
|
||||
body: userData,
|
||||
log: false,
|
||||
}).then((response) => {
|
||||
return;
|
||||
});
|
||||
});
|
||||
//Create user through API
|
||||
createUser();
|
||||
|
||||
// Go to the user and delete them
|
||||
cy.umbracoSection('users');
|
||||
@@ -135,6 +88,5 @@ context('Users', () => {
|
||||
|
||||
// assert deletion succeeds
|
||||
cy.umbracoSuccessNotification().should('be.visible');
|
||||
cy.umbracoEnsureUserEmailNotExists(email);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,5 +26,72 @@
|
||||
|
||||
import {Command} from 'umbraco-cypress-testhelpers';
|
||||
import {Chainable} from './chainable';
|
||||
import { JsonHelper } from 'umbraco-cypress-testhelpers';
|
||||
new Chainable();
|
||||
new Command().registerCypressCommands();
|
||||
|
||||
Cypress.Commands.add('umbracoCreateLanguage', (culture, isMandatory = false, fallbackLanguageId = 1) => {
|
||||
|
||||
var langData =
|
||||
{
|
||||
"culture": culture,
|
||||
"isMandatory": isMandatory,
|
||||
"fallbackLanguageId": fallbackLanguageId
|
||||
};
|
||||
|
||||
// Create language through API
|
||||
cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/umbraco/backoffice/umbracoapi/language/SaveLanguage',
|
||||
followRedirect: true,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'X-UMB-XSRF-TOKEN': token.value,
|
||||
},
|
||||
body: langData,
|
||||
log: false,
|
||||
}).then((response) => {
|
||||
return;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('umbracoEnsureLanguageCultureNotExists', (culture) => {
|
||||
cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
|
||||
cy.request({
|
||||
method: 'GET',
|
||||
url: '/umbraco/backoffice/umbracoapi/language/GetAllLanguages',
|
||||
followRedirect: true,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'X-UMB-XSRF-TOKEN': token.value,
|
||||
},
|
||||
log: false,
|
||||
}).then((response) => {
|
||||
const searchBody = JsonHelper.getBody(response);
|
||||
if (searchBody.length > 0) {
|
||||
let languageId = null;
|
||||
for (const sb of searchBody) {
|
||||
if (sb.culture === culture) {
|
||||
languageId = sb.id;
|
||||
}
|
||||
}
|
||||
|
||||
if (languageId !== null) {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/umbraco/backoffice/umbracoapi/language/DeleteLanguage?id=' + languageId,
|
||||
followRedirect: false,
|
||||
headers: {
|
||||
ContentType: 'application/json',
|
||||
'X-UMB-XSRF-TOKEN': token.value,
|
||||
},
|
||||
}).then((resp) => {
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,3 +3,28 @@
|
||||
|
||||
// type definitions for custom commands like "createDefaultTodos"
|
||||
// <reference types="support" />
|
||||
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Cypress {
|
||||
interface Chainable<Subject> {
|
||||
/**
|
||||
* Checks to see if the language with specified culture does not exist
|
||||
* If it does it will automatically delete it
|
||||
* @param {string} culture Culture of language to delete
|
||||
* @example cy.umbracoEnsureLanguageCultureNotExists('da-DK');
|
||||
*/
|
||||
umbracoEnsureLanguageCultureNotExists: (culture: string) => Chainable<void>;
|
||||
/**
|
||||
* Creates a language from a culture
|
||||
* @param {string} culture Culture of the language - fx "da_DK"
|
||||
* @param {boolean} isMandatory Set whether the language is mandatory or not. Defaults to false
|
||||
* @param {string} fallbackLanguageId of the language to fallback to. Defaults to 1 which is en_US
|
||||
* @example cy.umbracoCreateLanguage('da', true, '1');
|
||||
*/
|
||||
umbracoCreateLanguage: (culture: string, isMandatory: boolean, fallbackLanguageId: string) => Chainable<void>;
|
||||
}
|
||||
}
|
||||
}
|
||||
1992
tests/Umbraco.Tests.AcceptanceTest/package-lock.json
generated
1992
tests/Umbraco.Tests.AcceptanceTest/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,11 +9,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.2",
|
||||
"cypress": "^6.8.0",
|
||||
"cypress": "8.4.1",
|
||||
"del": "^6.0.0",
|
||||
"ncp": "^2.0.0",
|
||||
"prompt": "^1.2.0",
|
||||
"umbraco-cypress-testhelpers": "^1.0.0-beta-58"
|
||||
"umbraco-cypress-testhelpers": "^1.0.0-beta-62"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": "^3.9.2"
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Umbraco.Cms.Tests.Common.Builders
|
||||
public ContentBuilder WithContentType(IContentType contentType)
|
||||
{
|
||||
_contentTypeBuilder = null;
|
||||
_contentType = contentType;
|
||||
_contentType = contentType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -172,6 +172,11 @@ namespace Umbraco.Cms.Tests.Common.Builders
|
||||
content.SortOrder = sortOrder;
|
||||
content.Trashed = trashed;
|
||||
|
||||
if (contentType.DefaultTemplate?.Id > 0)
|
||||
{
|
||||
content.TemplateId = contentType.DefaultTemplate.Id;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> cultureName in _cultureNames)
|
||||
{
|
||||
content.SetCultureName(cultureName.Value, cultureName.Key);
|
||||
|
||||
221
tests/Umbraco.Tests.Common/Builders/ContentDataBuilder.cs
Normal file
221
tests/Umbraco.Tests.Common/Builders/ContentDataBuilder.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Moq;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders
|
||||
{
|
||||
|
||||
public class ContentDataBuilder : BuilderBase<ContentData>, IWithNameBuilder
|
||||
{
|
||||
private string _name;
|
||||
private DateTime? _now;
|
||||
private string _segment;
|
||||
private int? _versionId;
|
||||
private int? _writerId;
|
||||
private int? _templateId;
|
||||
private bool? _published;
|
||||
private Dictionary<string, PropertyData[]> _properties;
|
||||
private Dictionary<string, CultureVariation> _cultureInfos;
|
||||
|
||||
string IWithNameBuilder.Name
|
||||
{
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithVersionDate(DateTime now)
|
||||
{
|
||||
_now = now;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithUrlSegment(string segment)
|
||||
{
|
||||
_segment = segment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithVersionId(int versionId)
|
||||
{
|
||||
_versionId = versionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithWriterId(int writerId)
|
||||
{
|
||||
_writerId = writerId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithTemplateId(int templateId)
|
||||
{
|
||||
_templateId = templateId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithPublished(bool published)
|
||||
{
|
||||
_published = published;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithProperties(Dictionary<string, PropertyData[]> properties)
|
||||
{
|
||||
_properties = properties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentDataBuilder WithCultureInfos(Dictionary<string, CultureVariation> cultureInfos)
|
||||
{
|
||||
_cultureInfos = cultureInfos;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build and dynamically update an existing content type
|
||||
/// </summary>
|
||||
/// <typeparam name="TContentType"></typeparam>
|
||||
/// <param name="shortStringHelper"></param>
|
||||
/// <param name="propertyDataTypes"></param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="contentTypeAlias">
|
||||
/// Will configure the content type with this alias/name if supplied when it's not already set on the content type.
|
||||
/// </param>
|
||||
/// <param name="autoCreateCultureNames"></param>
|
||||
/// <returns></returns>
|
||||
public ContentData Build<TContentType>(
|
||||
IShortStringHelper shortStringHelper,
|
||||
Dictionary<string, IDataType> propertyDataTypes,
|
||||
TContentType contentType,
|
||||
string contentTypeAlias = null,
|
||||
bool autoCreateCultureNames = false) where TContentType : class, IContentTypeComposition
|
||||
{
|
||||
if (_name.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new InvalidOperationException("Cannot build without a name");
|
||||
}
|
||||
_segment ??= _name.ToLower().ReplaceNonAlphanumericChars('-');
|
||||
|
||||
// create or copy the current culture infos for the content
|
||||
Dictionary<string, CultureVariation> contentCultureInfos = _cultureInfos == null
|
||||
? new Dictionary<string, CultureVariation>()
|
||||
: new Dictionary<string, CultureVariation>(_cultureInfos);
|
||||
|
||||
contentType.Alias ??= contentTypeAlias;
|
||||
contentType.Name ??= contentTypeAlias;
|
||||
contentType.Key = contentType.Key == default ? Guid.NewGuid() : contentType.Key;
|
||||
contentType.Id = contentType.Id == default ? Math.Abs(contentTypeAlias.GetHashCode()) : contentType.Id;
|
||||
|
||||
if (_properties == null)
|
||||
{
|
||||
_properties = new Dictionary<string, PropertyData[]>();
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, PropertyData[]> prop in _properties)
|
||||
{
|
||||
//var dataType = new DataType(new VoidEditor("Label", Mock.Of<IDataValueEditorFactory>()), new ConfigurationEditorJsonSerializer())
|
||||
//{
|
||||
// Id = 4
|
||||
//};
|
||||
|
||||
if (!propertyDataTypes.TryGetValue(prop.Key, out IDataType dataType))
|
||||
{
|
||||
dataType = propertyDataTypes.First().Value;
|
||||
}
|
||||
|
||||
var propertyType = new PropertyType(shortStringHelper, dataType, prop.Key);
|
||||
|
||||
// check each property for culture and set variations accordingly,
|
||||
// this will also ensure that we have the correct culture name on the content
|
||||
// set for each culture too.
|
||||
foreach (PropertyData cultureValue in prop.Value.Where(x => !x.Culture.IsNullOrWhiteSpace()))
|
||||
{
|
||||
// set the property type to vary based on the values
|
||||
propertyType.Variations |= ContentVariation.Culture;
|
||||
|
||||
// if there isn't already a culture, then add one with the default name
|
||||
if (autoCreateCultureNames && !contentCultureInfos.TryGetValue(cultureValue.Culture, out CultureVariation cultureVariation))
|
||||
{
|
||||
cultureVariation = new CultureVariation
|
||||
{
|
||||
Date = DateTime.Now,
|
||||
IsDraft = true,
|
||||
Name = _name,
|
||||
UrlSegment = _segment
|
||||
};
|
||||
contentCultureInfos[cultureValue.Culture] = cultureVariation;
|
||||
}
|
||||
}
|
||||
|
||||
// set variations for segments if there is any
|
||||
if (prop.Value.Any(x => !x.Segment.IsNullOrWhiteSpace()))
|
||||
{
|
||||
propertyType.Variations |= ContentVariation.Segment;
|
||||
contentType.Variations |= ContentVariation.Segment;
|
||||
}
|
||||
|
||||
if (!contentType.PropertyTypeExists(propertyType.Alias))
|
||||
{
|
||||
contentType.AddPropertyType(propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
if (contentCultureInfos.Count > 0)
|
||||
{
|
||||
contentType.Variations |= ContentVariation.Culture;
|
||||
WithCultureInfos(contentCultureInfos);
|
||||
}
|
||||
|
||||
var result = Build();
|
||||
return result;
|
||||
}
|
||||
|
||||
public override ContentData Build()
|
||||
{
|
||||
var now = _now ?? DateTime.Now;
|
||||
var versionId = _versionId ?? 1;
|
||||
var writerId = _writerId ?? -1;
|
||||
var templateId = _templateId ?? 0;
|
||||
var published = _published ?? true;
|
||||
var properties = _properties ?? new Dictionary<string, PropertyData[]>();
|
||||
var cultureInfos = _cultureInfos ?? new Dictionary<string, CultureVariation>();
|
||||
var segment = _segment ?? _name.ToLower().ReplaceNonAlphanumericChars('-');
|
||||
|
||||
var contentData = new ContentData(
|
||||
_name,
|
||||
segment,
|
||||
versionId,
|
||||
now,
|
||||
writerId,
|
||||
templateId,
|
||||
published,
|
||||
properties,
|
||||
cultureInfos);
|
||||
|
||||
return contentData;
|
||||
}
|
||||
|
||||
public static ContentData CreateBasic(string name, DateTime? versionDate = null)
|
||||
=> new ContentDataBuilder()
|
||||
.WithName(name)
|
||||
.WithVersionDate(versionDate ?? DateTime.Now)
|
||||
.Build();
|
||||
|
||||
public static ContentData CreateVariant(string name, Dictionary<string, CultureVariation> cultureInfos, DateTime? versionDate = null, bool published = true)
|
||||
=> new ContentDataBuilder()
|
||||
.WithName(name)
|
||||
.WithVersionDate(versionDate ?? DateTime.Now)
|
||||
.WithCultureInfos(cultureInfos)
|
||||
.WithPublished(published)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
96
tests/Umbraco.Tests.Common/Builders/ContentNodeKitBuilder.cs
Normal file
96
tests/Umbraco.Tests.Common/Builders/ContentNodeKitBuilder.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders
|
||||
{
|
||||
public class ContentNodeKitBuilder : BuilderBase<ContentNodeKit>
|
||||
{
|
||||
private int _contentTypeId;
|
||||
private ContentNode _contentNode;
|
||||
private ContentData _draftData;
|
||||
private ContentData _publishedData;
|
||||
|
||||
public ContentNodeKitBuilder WithContentNode(ContentNode contentNode)
|
||||
{
|
||||
_contentNode = contentNode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentNodeKitBuilder WithContentNode(int id, Guid uid, int level, string path, int sortOrder, int parentContentId, DateTime createDate, int creatorId)
|
||||
{
|
||||
_contentNode = new ContentNode(id, uid, level, path, sortOrder, parentContentId, createDate, creatorId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentNodeKitBuilder WithContentTypeId(int contentTypeId)
|
||||
{
|
||||
_contentTypeId = contentTypeId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentNodeKitBuilder WithDraftData(ContentData draftData)
|
||||
{
|
||||
_draftData = draftData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContentNodeKitBuilder WithPublishedData(ContentData publishedData)
|
||||
{
|
||||
_publishedData = publishedData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override ContentNodeKit Build()
|
||||
{
|
||||
var data = new ContentNodeKit(_contentNode, _contentTypeId, _draftData, _publishedData);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a ContentNodeKit
|
||||
/// </summary>
|
||||
/// <param name="contentTypeId"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="sortOrder"></param>
|
||||
/// <param name="level">
|
||||
/// Optional. Will get calculated based on the path value if not specified.
|
||||
/// </param>
|
||||
/// <param name="parentContentId">
|
||||
/// Optional. Will get calculated based on the path value if not specified.
|
||||
/// </param>
|
||||
/// <param name="creatorId"></param>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="createDate"></param>
|
||||
/// <param name="draftData"></param>
|
||||
/// <param name="publishedData"></param>
|
||||
/// <returns></returns>
|
||||
public static ContentNodeKit CreateWithContent(
|
||||
int contentTypeId,
|
||||
int id,
|
||||
string path,
|
||||
int? sortOrder = null,
|
||||
int? level = null,
|
||||
int? parentContentId = null,
|
||||
int creatorId = -1,
|
||||
Guid? uid = null,
|
||||
DateTime? createDate = null,
|
||||
ContentData draftData = null,
|
||||
ContentData publishedData = null)
|
||||
{
|
||||
var pathParts = path.Split(',');
|
||||
if (pathParts.Length >= 2)
|
||||
{
|
||||
parentContentId ??= int.Parse(pathParts[^2]);
|
||||
}
|
||||
|
||||
return new ContentNodeKitBuilder()
|
||||
.WithContentTypeId(contentTypeId)
|
||||
.WithContentNode(id, uid ?? Guid.NewGuid(), level ?? pathParts.Length - 1, path, sortOrder ?? 0, parentContentId.Value, createDate ?? DateTime.Now, creatorId)
|
||||
.WithDraftData(draftData)
|
||||
.WithPublishedData(publishedData)
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Interfaces;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
@@ -113,6 +114,7 @@ namespace Umbraco.Cms.Tests.Common.Builders
|
||||
contentType.CreatorId = GetCreatorId();
|
||||
contentType.Trashed = GetTrashed();
|
||||
contentType.IsContainer = GetIsContainer();
|
||||
contentType.HistoryCleanup = new HistoryCleanup();
|
||||
|
||||
contentType.Variations = contentVariation;
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Cms.Tests.Common.Builders.Interfaces
|
||||
{
|
||||
public interface IWithAllowAsRootBuilder
|
||||
{
|
||||
bool? AllowAsRoot { get; set; }
|
||||
}
|
||||
}
|
||||
36
tests/Umbraco.Tests.Common/Builders/PropertyDataBuilder.cs
Normal file
36
tests/Umbraco.Tests.Common/Builders/PropertyDataBuilder.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Builders
|
||||
{
|
||||
public class PropertyDataBuilder : BuilderBase<Dictionary<string, PropertyData[]>>
|
||||
{
|
||||
private readonly Dictionary<string, List<PropertyData>> _properties = new();
|
||||
|
||||
public PropertyDataBuilder WithPropertyData(string alias, PropertyData propertyData)
|
||||
{
|
||||
if (!_properties.TryGetValue(alias, out List<PropertyData> propertyDataCollection))
|
||||
{
|
||||
propertyDataCollection = new List<PropertyData>();
|
||||
_properties[alias] = propertyDataCollection;
|
||||
}
|
||||
|
||||
propertyDataCollection.Add(propertyData);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyDataBuilder WithPropertyData(string alias, object value, string culture = null, string segment = null)
|
||||
=> WithPropertyData(alias, new PropertyData
|
||||
{
|
||||
Culture = culture ?? string.Empty,
|
||||
Segment = segment ?? string.Empty,
|
||||
Value = value
|
||||
});
|
||||
|
||||
public override Dictionary<string, PropertyData[]> Build()
|
||||
=> _properties.ToDictionary(x => x.Key, x => x.Value.ToArray());
|
||||
}
|
||||
}
|
||||
152
tests/Umbraco.Tests.Common/Published/PublishedContentXml.cs
Normal file
152
tests/Umbraco.Tests.Common/Published/PublishedContentXml.cs
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Published
|
||||
{
|
||||
public static class PublishedContentXml
|
||||
{
|
||||
// The content XML that was used for the old PublishContentCacheTests
|
||||
public static string PublishContentCacheTestsXml()
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?><!DOCTYPE root[
|
||||
<!ELEMENT Home ANY>
|
||||
<!ATTLIST Home id ID #REQUIRED>
|
||||
|
||||
]>
|
||||
<root id=""-1"">
|
||||
<Home id=""1046"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""2"" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" nodeName=""Home"" urlName=""home"" writerName=""admin"" creatorName=""admin"" path=""-1,1046"" isDoc=""""><content><![CDATA[]]></content>
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""1"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc=""""><content><![CDATA[]]></content>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""1"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""2"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""2"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<Home id=""1177"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""2"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub'Apostrophe"" urlName=""sub'apostrophe"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1177"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
</Home>
|
||||
<Home id=""1172"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1045"" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test"" writerName=""admin"" creatorName=""admin"" path=""-1,1172"" isDoc="""" />
|
||||
</root>";
|
||||
|
||||
// The content XML that was used in the old BaseWebTest class
|
||||
public static string BaseWebTestXml(int templateId)
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Home ANY>
|
||||
<!ATTLIST Home id ID #REQUIRED>
|
||||
<!ELEMENT CustomDocument ANY>
|
||||
<!ATTLIST CustomDocument id ID #REQUIRED>
|
||||
]>
|
||||
<root id=""-1"">
|
||||
<Home id=""1046"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" nodeName=""Home"" urlName=""home"" writerName=""admin"" creatorName=""admin"" path=""-1,1046"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[this/is/my/alias, anotheralias]]></umbracoUrlAlias>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""">
|
||||
<content><![CDATA[<div>This is some content</div>]]></content>
|
||||
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>
|
||||
<creatorName><![CDATA[Custom data with same property name as the member name]]></creatorName>
|
||||
</Home>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""" />
|
||||
<CustomDocument id=""1179"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 3 with accént character"" urlName=""custom-sub-3-with-accént-character"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1179"" isDoc="""" />
|
||||
<CustomDocument id=""1180"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 4 with æøå"" urlName=""custom-sub-4-with-æøå"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1180"" isDoc="""" />
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
</Home>
|
||||
<CustomDocument id=""1172"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1172"" isDoc="""" />
|
||||
</root>";
|
||||
|
||||
// The content XML that was used in the old TestWithDatabase class
|
||||
public static string TestWithDatabaseXml(int templateId)
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Home ANY>
|
||||
<!ATTLIST Home id ID #REQUIRED>
|
||||
<!ELEMENT CustomDocument ANY>
|
||||
<!ATTLIST CustomDocument id ID #REQUIRED>
|
||||
]>
|
||||
<root id=""-1"">
|
||||
<Home id=""1046"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" nodeName=""Home"" urlName=""home"" writerName=""admin"" creatorName=""admin"" path=""-1,1046"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[this/is/my/alias, anotheralias]]></umbracoUrlAlias>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""">
|
||||
<content><![CDATA[<div>This is some content</div>]]></content>
|
||||
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>
|
||||
<creatorName><![CDATA[Custom data with same property name as the member name]]></creatorName>
|
||||
</Home>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""" />
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
</Home>
|
||||
<CustomDocument id=""1172"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1172"" isDoc="""" />
|
||||
</root>";
|
||||
|
||||
// The content XML that was used in the old PublishedContentTest class
|
||||
public static string PublishedContentTestXml(int templateId, Guid node1173Guid)
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Home ANY>
|
||||
<!ATTLIST Home id ID #REQUIRED>
|
||||
<!ELEMENT CustomDocument ANY>
|
||||
<!ATTLIST CustomDocument id ID #REQUIRED>
|
||||
]>
|
||||
<root id=""-1"">
|
||||
<Home id=""1046"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" nodeName=""Home"" urlName=""home"" writerName=""admin"" creatorName=""admin"" path=""-1,1046"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[this/is/my/alias, anotheralias]]></umbracoUrlAlias>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
<testRecursive><![CDATA[This is the recursive val]]></testRecursive>
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""" key=""" + node1173Guid + @""">
|
||||
<content><![CDATA[<div>This is some content</div>]]></content>
|
||||
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
|
||||
<testRecursive><![CDATA[]]></testRecursive>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>
|
||||
<creatorName><![CDATA[Custom data with same property name as the member name]]></creatorName>
|
||||
<testRecursive><![CDATA[]]></testRecursive>
|
||||
</Home>
|
||||
<CustomDocument id=""117"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2018-07-18T10:06:37"" updateDate=""2018-07-18T10:06:37"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,117"" isDoc="""">
|
||||
<umbracoNaviHide>0</umbracoNaviHide>
|
||||
</CustomDocument>
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""">
|
||||
<umbracoNaviHide>0</umbracoNaviHide>
|
||||
</CustomDocument>
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""">
|
||||
<umbracoNaviHide>0</umbracoNaviHide>
|
||||
<CustomDocument id=""1179"" parentID=""1178"" level=""4"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub sub 1"" urlName=""custom-sub-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178,1179"" isDoc="""" />
|
||||
</CustomDocument>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""5"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""" key=""CDB83BBC-A83B-4BA6-93B8-AADEF67D3C09"">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
</Home>
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<CustomDocument id=""4444"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,4444"" isDoc="""">
|
||||
<selectedNodes><![CDATA[1172,1176,1173]]></selectedNodes>
|
||||
</CustomDocument>
|
||||
</Home>
|
||||
<CustomDocument id=""1172"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1172"" isDoc="""" />
|
||||
</root>";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using System.Linq;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using System;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Moq;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Published
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts legacy Umbraco XML structures to NuCache <see cref="ContentNodeKit"/> collections
|
||||
/// to populate a test implementation of <see cref="INuCacheContentService"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does not support variant data because the XML structure doesn't support variant data.
|
||||
/// </remarks>
|
||||
public static class PublishedContentXmlAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate a collection of <see cref="ContentNodeKit"/> based on legacy umbraco XML
|
||||
/// </summary>
|
||||
/// <param name="xml">The legacy umbraco XML</param>
|
||||
/// <param name="shortStringHelper"></param>
|
||||
/// <param name="contentTypes">Dynamically generates a list of <see cref="ContentType"/>s based on the XML data</param>
|
||||
/// <param name="dataTypes">Dynamically generates a list of <see cref="DataType"/> for tests</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<ContentNodeKit> GetContentNodeKits(
|
||||
string xml,
|
||||
IShortStringHelper shortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes)
|
||||
{
|
||||
// use the label data type for all data for these tests except in the case
|
||||
// where a property is named 'content', in which case use the RTE.
|
||||
var serializer = new ConfigurationEditorJsonSerializer();
|
||||
var labelDataType = new DataType(new VoidEditor("Label", Mock.Of<IDataValueEditorFactory>()), serializer) { Id = 3 };
|
||||
var rteDataType = new DataType(new VoidEditor("RTE", Mock.Of<IDataValueEditorFactory>()), serializer) { Id = 4 };
|
||||
dataTypes = new[] { labelDataType, rteDataType };
|
||||
|
||||
var kitsAndXml = new List<(ContentNodeKit kit, XElement node)>();
|
||||
|
||||
var xDoc = XDocument.Parse(xml);
|
||||
IEnumerable<XElement> nodes = xDoc.XPathSelectElements("//*[@isDoc]");
|
||||
foreach (XElement node in nodes)
|
||||
{
|
||||
var id = node.AttributeValue<int>("id");
|
||||
Guid key = node.AttributeValue<Guid?>("key") ?? id.ToGuid();
|
||||
|
||||
var propertyElements = node.Elements().Where(x => x.Attribute("id") == null);
|
||||
var properties = new Dictionary<string, PropertyData[]>();
|
||||
foreach(XElement propertyElement in propertyElements)
|
||||
{
|
||||
properties[propertyElement.Name.LocalName] = new[]
|
||||
{
|
||||
// TODO: builder?
|
||||
new PropertyData
|
||||
{
|
||||
Culture = string.Empty,
|
||||
Segment = string.Empty,
|
||||
Value = propertyElement.Value
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var contentData = new ContentDataBuilder()
|
||||
.WithName(node.AttributeValue<string>("nodeName"))
|
||||
.WithProperties(properties)
|
||||
.WithPublished(true)
|
||||
.WithTemplateId(node.AttributeValue<int>("template"))
|
||||
.WithUrlSegment(node.AttributeValue<string>("urlName"))
|
||||
.WithVersionDate(node.AttributeValue<DateTime>("updateDate"))
|
||||
.WithWriterId(node.AttributeValue<int>("writerID"))
|
||||
.Build();
|
||||
|
||||
ContentNodeKit kit = ContentNodeKitBuilder.CreateWithContent(
|
||||
node.AttributeValue<int>("nodeType"),
|
||||
id,
|
||||
node.AttributeValue<string>("path"),
|
||||
node.AttributeValue<int>("sortOrder"),
|
||||
node.AttributeValue<int>("level"),
|
||||
node.AttributeValue<int>("parentID"),
|
||||
node.AttributeValue<int>("creatorID"),
|
||||
key,
|
||||
node.AttributeValue<DateTime>("createDate"),
|
||||
contentData,
|
||||
contentData);
|
||||
|
||||
kitsAndXml.Add((kit, node));
|
||||
}
|
||||
|
||||
// put together the unique content types
|
||||
var contentTypesIdToType = new Dictionary<int, ContentType>();
|
||||
foreach((ContentNodeKit kit, XElement node) in kitsAndXml)
|
||||
{
|
||||
if (!contentTypesIdToType.TryGetValue(kit.ContentTypeId, out ContentType contentType))
|
||||
{
|
||||
contentType = new ContentType(shortStringHelper, -1)
|
||||
{
|
||||
Id = kit.ContentTypeId,
|
||||
Alias = node.Name.LocalName
|
||||
};
|
||||
SetContentTypeProperties(shortStringHelper, labelDataType, rteDataType, kit, contentType);
|
||||
contentTypesIdToType[kit.ContentTypeId] = contentType;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we've already created it but might need to add properties
|
||||
SetContentTypeProperties(shortStringHelper, labelDataType, rteDataType, kit, contentType);
|
||||
}
|
||||
}
|
||||
|
||||
contentTypes = contentTypesIdToType.Values.ToArray();
|
||||
|
||||
return kitsAndXml.Select(x => x.kit);
|
||||
}
|
||||
|
||||
private static void SetContentTypeProperties(IShortStringHelper shortStringHelper, DataType labelDataType, DataType rteDataType, ContentNodeKit kit, ContentType contentType)
|
||||
{
|
||||
foreach (KeyValuePair<string, PropertyData[]> property in kit.DraftData.Properties)
|
||||
{
|
||||
var propertyType = new PropertyType(shortStringHelper, labelDataType, property.Key);
|
||||
|
||||
if (!contentType.PropertyTypeExists(propertyType.Alias))
|
||||
{
|
||||
if (propertyType.Alias == "content")
|
||||
{
|
||||
propertyType.DataTypeId = rteDataType.Id;
|
||||
}
|
||||
contentType.AddPropertyType(propertyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Published
|
||||
{
|
||||
|
||||
public class PublishedSnapshotTestObjects
|
||||
{
|
||||
[PublishedModel("element1")]
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
|
||||
public class AutoPublishedContentType : PublishedContentType
|
||||
{
|
||||
private static readonly IPublishedPropertyType Default;
|
||||
|
||||
static AutoPublishedContentType()
|
||||
{
|
||||
var configurationEditorJsonSerializer = new ConfigurationEditorJsonSerializer();
|
||||
var jsonSerializer = new JsonNetSerializer();
|
||||
var dataTypeServiceMock = new Mock<IDataTypeService>();
|
||||
|
||||
var dataType = new DataType(
|
||||
new VoidEditor(
|
||||
Mock.Of<IDataValueEditorFactory>()),
|
||||
configurationEditorJsonSerializer)
|
||||
{
|
||||
Id = 666
|
||||
};
|
||||
dataTypeServiceMock.Setup(x => x.GetAll()).Returns(dataType.Yield);
|
||||
|
||||
var factory = new PublishedContentTypeFactory(Mock.Of<IPublishedModelFactory>(), new PropertyValueConverterCollection(() => Enumerable.Empty<IPropertyValueConverter>()), dataTypeServiceMock.Object);
|
||||
Default = factory.CreatePropertyType("*", 666);
|
||||
}
|
||||
|
||||
public AutoPublishedContentType(Guid key, int id, string alias, IEnumerable<PublishedPropertyType> propertyTypes)
|
||||
: base(key, id, alias, PublishedItemType.Content, Enumerable.Empty<string>(), propertyTypes, ContentVariation.Nothing)
|
||||
{
|
||||
}
|
||||
|
||||
public AutoPublishedContentType(Guid key, int id, string alias, Func<IPublishedContentType, IEnumerable<IPublishedPropertyType>> propertyTypes)
|
||||
: base(key, id, alias, PublishedItemType.Content, Enumerable.Empty<string>(), propertyTypes, ContentVariation.Nothing)
|
||||
{
|
||||
}
|
||||
|
||||
public AutoPublishedContentType(Guid key, int id, string alias, IEnumerable<string> compositionAliases, IEnumerable<PublishedPropertyType> propertyTypes)
|
||||
: base(key, id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, ContentVariation.Nothing)
|
||||
{
|
||||
}
|
||||
|
||||
public AutoPublishedContentType(Guid key, int id, string alias, IEnumerable<string> compositionAliases, Func<IPublishedContentType, IEnumerable<IPublishedPropertyType>> propertyTypes)
|
||||
: base(key, id, alias, PublishedItemType.Content, compositionAliases, propertyTypes, ContentVariation.Nothing)
|
||||
{
|
||||
}
|
||||
|
||||
public override IPublishedPropertyType GetPropertyType(string alias)
|
||||
{
|
||||
IPublishedPropertyType propertyType = base.GetPropertyType(alias);
|
||||
return propertyType ?? Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
[PublishedModel("ContentType2")]
|
||||
public class ContentType2 : PublishedContentModel
|
||||
{
|
||||
public ContentType2(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{
|
||||
}
|
||||
|
||||
public int Prop1 => this.Value<int>(Mock.Of<IPublishedValueFallback>(), "prop1");
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
[PublishedModel("ContentType2Sub")]
|
||||
public class ContentType2Sub : ContentType2
|
||||
{
|
||||
public ContentType2Sub(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.PublishedCache.Internal;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
public class InternalPublishedPropertyWithLanguageVariants : InternalPublishedProperty
|
||||
{
|
||||
private readonly IDictionary<string, object> _solidSourceValues = new Dictionary<string, object>();
|
||||
private readonly IDictionary<string, object> _solidValues = new Dictionary<string, object>();
|
||||
private readonly IDictionary<string, object> _solidXPathValues = new Dictionary<string, object>();
|
||||
|
||||
public override object GetSourceValue(string culture = null, string segment = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
return base.GetSourceValue(culture, segment);
|
||||
}
|
||||
|
||||
return _solidSourceValues.ContainsKey(culture) ? _solidSourceValues[culture] : null;
|
||||
}
|
||||
|
||||
public override object GetValue(string culture = null, string segment = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
return base.GetValue(culture, segment);
|
||||
}
|
||||
|
||||
return _solidValues.ContainsKey(culture) ? _solidValues[culture] : null;
|
||||
}
|
||||
|
||||
public override object GetXPathValue(string culture = null, string segment = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
return base.GetXPathValue(culture, segment);
|
||||
}
|
||||
|
||||
return _solidXPathValues.ContainsKey(culture) ? _solidXPathValues[culture] : null;
|
||||
}
|
||||
|
||||
public override bool HasValue(string culture = null, string segment = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
return base.HasValue(culture, segment);
|
||||
}
|
||||
|
||||
return _solidSourceValues.ContainsKey(culture);
|
||||
}
|
||||
|
||||
public void SetSourceValue(string culture, object value, bool defaultValue = false)
|
||||
{
|
||||
_solidSourceValues.Add(culture, value);
|
||||
if (defaultValue)
|
||||
{
|
||||
SolidSourceValue = value;
|
||||
SolidHasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue(string culture, object value, bool defaultValue = false)
|
||||
{
|
||||
_solidValues.Add(culture, value);
|
||||
if (defaultValue)
|
||||
{
|
||||
SolidValue = value;
|
||||
SolidHasValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetXPathValue(string culture, object value, bool defaultValue = false)
|
||||
{
|
||||
_solidXPathValues.Add(culture, value);
|
||||
if (defaultValue)
|
||||
{
|
||||
SolidXPathValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
public class PublishedContentStrong1 : PublishedContentModel
|
||||
{
|
||||
public PublishedContentStrong1(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{
|
||||
}
|
||||
|
||||
public int StrongValue => this.Value<int>(Mock.Of<IPublishedValueFallback>(), "strongValue");
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
public class PublishedContentStrong1Sub : PublishedContentStrong1
|
||||
{
|
||||
public PublishedContentStrong1Sub(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{
|
||||
}
|
||||
|
||||
public int AnotherValue => this.Value<int>(Mock.Of<IPublishedValueFallback>(), "anotherValue");
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers.PublishedContent
|
||||
{
|
||||
public class PublishedContentStrong2 : PublishedContentModel
|
||||
{
|
||||
public PublishedContentStrong2(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{
|
||||
}
|
||||
|
||||
public int StrongValue => this.Value<int>(Mock.Of<IPublishedValueFallback>(), "strongValue");
|
||||
}
|
||||
}
|
||||
12
tests/Umbraco.Tests.Common/TestLastChanceFinder.cs
Normal file
12
tests/Umbraco.Tests.Common/TestLastChanceFinder.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common
|
||||
{
|
||||
public class TestLastChanceFinder : IContentLastChanceFinder
|
||||
{
|
||||
public bool TryFindContent(IPublishedRequestBuilder frequest) => false;
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,14 @@ namespace Umbraco.Cms.Tests.Common
|
||||
{
|
||||
public class TestPublishedSnapshotAccessor : IPublishedSnapshotAccessor
|
||||
{
|
||||
private IPublishedSnapshot _snapshot = null;
|
||||
|
||||
public bool TryGetPublishedSnapshot(out IPublishedSnapshot publishedSnapshot)
|
||||
{
|
||||
publishedSnapshot = null;
|
||||
return false;
|
||||
publishedSnapshot = _snapshot;
|
||||
return _snapshot != null;
|
||||
}
|
||||
|
||||
public void SetCurrent(IPublishedSnapshot snapshot) => _snapshot = snapshot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Internal;
|
||||
using Umbraco.Cms.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.Testing
|
||||
{
|
||||
public abstract class TestOptionAttributeBase : Attribute
|
||||
{
|
||||
[Obsolete("This is not used anymore - Test classes are found using nunit helpers")]
|
||||
public static readonly List<Assembly> ScanAssemblies = new List<Assembly>();
|
||||
|
||||
public static TOptions GetTestOptions<TOptions>(MethodInfo method)
|
||||
@@ -29,26 +31,8 @@ namespace Umbraco.Cms.Tests.Common.Testing
|
||||
where TOptions : TestOptionAttributeBase, new()
|
||||
{
|
||||
TestContext.TestAdapter test = TestContext.CurrentContext.Test;
|
||||
var typeName = test.ClassName;
|
||||
var methodName = test.MethodName;
|
||||
|
||||
// This will only get types from whatever is already loaded in the app domain.
|
||||
var type = Type.GetType(typeName, false);
|
||||
if (type == null)
|
||||
{
|
||||
// automatically add the executing and calling assemblies to the list to scan for this type
|
||||
var scanAssemblies = ScanAssemblies.Union(new[] { Assembly.GetExecutingAssembly(), Assembly.GetCallingAssembly() }).ToList();
|
||||
|
||||
type = scanAssemblies
|
||||
.Select(assembly => assembly.GetType(typeName, false))
|
||||
.FirstOrDefault(x => x != null);
|
||||
if (type == null)
|
||||
{
|
||||
throw new PanicException($"Could not resolve the running test fixture from type name {typeName}.\n" +
|
||||
$"To use base classes from Umbraco.Tests, add your test assembly to TestOptionAttributeBase.ScanAssemblies");
|
||||
}
|
||||
}
|
||||
|
||||
var type = TestExecutionContext.CurrentContext.TestObject.GetType();
|
||||
MethodInfo methodInfo = type.GetMethod(methodName); // what about overloads?
|
||||
TOptions options = GetTestOptions<TOptions>(methodInfo);
|
||||
return options;
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Examine.Lucene" Version="2.0.0" />
|
||||
<PackageReference Include="Examine.Lucene" Version="2.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.10" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0">
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
@@ -24,7 +25,6 @@ using Umbraco.Cms.Tests.Integration.DependencyInjection;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Web.BackOffice.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Controllers;
|
||||
using Umbraco.Cms.Web.UI;
|
||||
using Umbraco.Cms.Web.Website.Controllers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -52,17 +52,22 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
|
||||
*
|
||||
* See https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests
|
||||
*/
|
||||
var factory = new UmbracoWebApplicationFactory<Startup>(CreateHostBuilder, BeforeHostStart);
|
||||
var factory = new UmbracoWebApplicationFactory<UmbracoTestServerTestBase>(CreateHostBuilder, BeforeHostStart);
|
||||
|
||||
// additional host configuration for web server integration tests
|
||||
Factory = factory.WithWebHostBuilder(builder =>
|
||||
{
|
||||
// Otherwise inferred as $(SolutionDir)/Umbraco.Tests.Integration (note lack of src/tests)
|
||||
builder.UseContentRoot(Assembly.GetExecutingAssembly().GetRootDirectorySafe());
|
||||
|
||||
// Executes after the standard ConfigureServices method
|
||||
builder.ConfigureTestServices(services =>
|
||||
|
||||
// Add a test auth scheme with a test auth handler to authn and assign the user
|
||||
services.AddAuthentication(TestAuthHandler.TestAuthenticationScheme)
|
||||
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(TestAuthHandler.TestAuthenticationScheme, options => { })));
|
||||
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(TestAuthHandler.TestAuthenticationScheme, options => { }));
|
||||
});
|
||||
|
||||
|
||||
Client = Factory.CreateClient(new WebApplicationFactoryClientOptions
|
||||
{
|
||||
@@ -141,7 +146,7 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
|
||||
|
||||
protected LinkGenerator LinkGenerator { get; private set; }
|
||||
|
||||
protected WebApplicationFactory<Startup> Factory { get; private set; }
|
||||
protected WebApplicationFactory<UmbracoTestServerTestBase> Factory { get; private set; }
|
||||
|
||||
public override void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
|
||||
@@ -118,13 +119,13 @@ namespace Umbraco.Cms.Tests.Integration.Testing
|
||||
|
||||
string filename = Path.Combine(s_filesPath, DatabaseName).ToUpper();
|
||||
|
||||
foreach (string database in s_localDbInstance.GetDatabases())
|
||||
Parallel.ForEach(s_localDbInstance.GetDatabases(), instance =>
|
||||
{
|
||||
if (database.StartsWith(filename))
|
||||
if (instance.StartsWith(filename))
|
||||
{
|
||||
s_localDbInstance.DropDatabase(database);
|
||||
s_localDbInstance.DropDatabase(instance);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_localDb.StopInstance(InstanceName);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Collections.Concurrent;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
|
||||
@@ -118,10 +119,7 @@ namespace Umbraco.Cms.Tests.Integration.Testing
|
||||
{
|
||||
}
|
||||
|
||||
foreach (TestDbMeta testDatabase in _testDatabases)
|
||||
{
|
||||
Drop(testDatabase);
|
||||
}
|
||||
Parallel.ForEach(_testDatabases, Drop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Tests.Integration.TestServerTest;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedContentQueryAccessorTests : UmbracoTestServerTestBase
|
||||
{
|
||||
[Test]
|
||||
public async Task PublishedContentQueryAccessor_WithRequestScope_WillProvideQuery()
|
||||
{
|
||||
HttpResponseMessage result = await Client.GetAsync("/demo-published-content-query-accessor");
|
||||
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
public class PublishedContentQueryAccessorTestController : Controller
|
||||
{
|
||||
private readonly IPublishedContentQueryAccessor _accessor;
|
||||
|
||||
public PublishedContentQueryAccessorTestController(IPublishedContentQueryAccessor accessor)
|
||||
{
|
||||
_accessor = accessor;
|
||||
}
|
||||
|
||||
[HttpGet("demo-published-content-query-accessor")]
|
||||
public IActionResult Test()
|
||||
{
|
||||
var success = _accessor.TryGetValue(out IPublishedContentQuery query);
|
||||
|
||||
if (!success || query == null)
|
||||
{
|
||||
throw new ApplicationException("It doesn't work");
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bogus;
|
||||
using Examine;
|
||||
using Lucene.Net.Util;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -47,6 +49,43 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Examine.Lucene.UmbracoExamine
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GivenIndexingDocument_WhenRichTextPropertyData_CanStoreImmenseFields()
|
||||
{
|
||||
using (GetSynchronousContentIndex(false, out UmbracoContentIndex index, out _, out ContentValueSetBuilder contentValueSetBuilder, null))
|
||||
{
|
||||
index.CreateIndex();
|
||||
|
||||
ContentType contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
contentType.AddPropertyType(new PropertyType(TestHelper.ShortStringHelper, "test", ValueStorageType.Ntext)
|
||||
{
|
||||
Alias = "rte",
|
||||
Name = "RichText",
|
||||
PropertyEditorAlias = Cms.Core.Constants.PropertyEditors.Aliases.TinyMce
|
||||
});
|
||||
|
||||
Content content = ContentBuilder.CreateBasicContent(contentType);
|
||||
content.Id = 555;
|
||||
content.Path = "-1,555";
|
||||
|
||||
var luceneStringFieldMaxLength = ByteBlockPool.BYTE_BLOCK_SIZE - 2;
|
||||
var faker = new Faker();
|
||||
var immenseText = faker.Random.String(length: luceneStringFieldMaxLength + 10);
|
||||
|
||||
content.Properties["rte"].SetValue(immenseText);
|
||||
|
||||
IEnumerable<ValueSet> valueSet = contentValueSetBuilder.GetValueSets(content);
|
||||
index.IndexItems(valueSet);
|
||||
|
||||
ISearchResults results = index.Searcher.CreateQuery().Id(555).Execute();
|
||||
ISearchResult result = results.First();
|
||||
|
||||
var key = $"{UmbracoExamineFieldNames.RawFieldPrefix}rte";
|
||||
Assert.IsTrue(result.Values.ContainsKey(key));
|
||||
Assert.Greater(result.Values[key].Length, luceneStringFieldMaxLength);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GivenIndexingDocument_WhenGridPropertyData_ThenDataIndexedInSegregatedFields()
|
||||
{
|
||||
|
||||
@@ -766,6 +766,77 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Packaging
|
||||
Assert.That(testContentType.ContentTypeCompositionExists("Seo"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImportDocumentType_NewTypeWithOmittedHistoryCleanupPolicy_InsertsDefaultPolicy()
|
||||
{
|
||||
// Arrange
|
||||
var withoutCleanupPolicy = XElement.Parse(ImportResources.SingleDocType);
|
||||
|
||||
// Act
|
||||
var contentTypes = PackageDataInstallation
|
||||
.ImportDocumentType(withoutCleanupPolicy, 0)
|
||||
.OfType<IContentTypeWithHistoryCleanup>();
|
||||
|
||||
// Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.NotNull(contentTypes.Single().HistoryCleanup);
|
||||
Assert.IsFalse(contentTypes.Single().HistoryCleanup.PreventCleanup);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImportDocumentType_WithHistoryCleanupPolicyElement_ImportsWithCorrectValues()
|
||||
{
|
||||
// Arrange
|
||||
var docTypeElement = XElement.Parse(ImportResources.SingleDocType_WithCleanupPolicy);
|
||||
|
||||
// Act
|
||||
var contentTypes = PackageDataInstallation
|
||||
.ImportDocumentType(docTypeElement, 0)
|
||||
.OfType<IContentTypeWithHistoryCleanup>();
|
||||
|
||||
// Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.NotNull(contentTypes.Single().HistoryCleanup);
|
||||
Assert.IsTrue(contentTypes.Single().HistoryCleanup.PreventCleanup);
|
||||
Assert.AreEqual(1, contentTypes.Single().HistoryCleanup.KeepAllVersionsNewerThanDays);
|
||||
Assert.AreEqual(2, contentTypes.Single().HistoryCleanup.KeepLatestVersionPerDayForDays);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ImportDocumentType_ExistingTypeWithOmittedHistoryCleanupPolicy_DoesNotOverwriteDatabaseContent()
|
||||
{
|
||||
// Arrange
|
||||
var withoutCleanupPolicy = XElement.Parse(ImportResources.SingleDocType);
|
||||
var withCleanupPolicy = XElement.Parse(ImportResources.SingleDocType_WithCleanupPolicy);
|
||||
|
||||
// Act
|
||||
var contentTypes = PackageDataInstallation
|
||||
.ImportDocumentType(withCleanupPolicy, 0)
|
||||
.OfType<IContentTypeWithHistoryCleanup>();
|
||||
|
||||
var contentTypesUpdated = PackageDataInstallation
|
||||
.ImportDocumentType(withoutCleanupPolicy, 0)
|
||||
.OfType<IContentTypeWithHistoryCleanup>();
|
||||
|
||||
// Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.NotNull(contentTypes.Single().HistoryCleanup);
|
||||
Assert.IsTrue(contentTypes.Single().HistoryCleanup.PreventCleanup);
|
||||
Assert.AreEqual(1, contentTypes.Single().HistoryCleanup.KeepAllVersionsNewerThanDays);
|
||||
Assert.AreEqual(2, contentTypes.Single().HistoryCleanup.KeepLatestVersionPerDayForDays);
|
||||
|
||||
Assert.NotNull(contentTypesUpdated.Single().HistoryCleanup);
|
||||
Assert.IsTrue(contentTypesUpdated.Single().HistoryCleanup.PreventCleanup);
|
||||
Assert.AreEqual(1, contentTypes.Single().HistoryCleanup.KeepAllVersionsNewerThanDays);
|
||||
Assert.AreEqual(2, contentTypes.Single().HistoryCleanup.KeepLatestVersionPerDayForDays);
|
||||
});
|
||||
}
|
||||
|
||||
private void AddLanguages()
|
||||
{
|
||||
var globalSettings = new GlobalSettings();
|
||||
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
@@ -73,7 +74,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
IScopeProvider provider = ScopeProvider;
|
||||
using (IScope scope = provider.CreateScope())
|
||||
{
|
||||
var templateRepo = new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<TemplateRepository>(), FileSystems, IOHelper, ShortStringHelper);
|
||||
var templateRepo = new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<TemplateRepository>(), FileSystems, IOHelper, ShortStringHelper, Mock.Of<IViewHelper>());
|
||||
ContentTypeRepository repository = ContentTypeRepository;
|
||||
Template[] templates = new[]
|
||||
{
|
||||
@@ -273,7 +274,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
Assert.AreNotEqual(propertyType.Key, Guid.Empty);
|
||||
}
|
||||
|
||||
TestHelper.AssertPropertyValuesAreEqual(fetched, contentType, ignoreProperties: new[] { "DefaultTemplate", "AllowedTemplates", "UpdateDate" });
|
||||
TestHelper.AssertPropertyValuesAreEqual(fetched, contentType, ignoreProperties: new[] { "DefaultTemplate", "AllowedTemplates", "UpdateDate", "HistoryCleanup" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,6 +379,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
//// Alias = display.Alias,
|
||||
Path = display.Path,
|
||||
//// AdditionalData = display.AdditionalData,
|
||||
HistoryCleanup = display.HistoryCleanup,
|
||||
|
||||
// ContentTypeBasic
|
||||
Alias = display.Alias,
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
|
||||
appCaches ??= AppCaches;
|
||||
|
||||
templateRepository = new TemplateRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<TemplateRepository>(), FileSystems, IOHelper, ShortStringHelper);
|
||||
templateRepository = new TemplateRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<TemplateRepository>(), FileSystems, IOHelper, ShortStringHelper, Mock.Of<IViewHelper>());
|
||||
var tagRepository = new TagRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<TagRepository>());
|
||||
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches, ShortStringHelper);
|
||||
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<LanguageRepository>(), globalSettings);
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositories
|
||||
{
|
||||
/// <remarks>
|
||||
/// v9 -> Tests.Integration
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class DocumentVersionRepositoryTest : UmbracoIntegrationTest
|
||||
{
|
||||
public IFileService FileService => GetRequiredService<IFileService>();
|
||||
public IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
public IContentService ContentService => GetRequiredService<IContentService>();
|
||||
|
||||
[Test]
|
||||
public void GetDocumentVersionsEligibleForCleanup_Always_ExcludesActiveVersions()
|
||||
{
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateId: template.Id);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var content = ContentBuilder.CreateSimpleContent(contentType);
|
||||
|
||||
ContentService.SaveAndPublish(content);
|
||||
// At this point content has 2 versions, a draft version and a published version.
|
||||
|
||||
ContentService.SaveAndPublish(content);
|
||||
// At this point content has 3 versions, a historic version, a draft version and a published version.
|
||||
|
||||
using (ScopeProvider.CreateScope())
|
||||
{
|
||||
var sut = new DocumentVersionRepository(ScopeAccessor);
|
||||
var results = sut.GetDocumentVersionsEligibleForCleanup();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(1, results.Count);
|
||||
Assert.AreEqual(1, results.First().VersionId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDocumentVersionsEligibleForCleanup_Always_ExcludesPinnedVersions()
|
||||
{
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateId: template.Id);
|
||||
ContentTypeService.Save(contentType);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var content = ContentBuilder.CreateSimpleContent(contentType);
|
||||
|
||||
ContentService.SaveAndPublish(content);
|
||||
// At this point content has 2 versions, a draft version and a published version.
|
||||
ContentService.SaveAndPublish(content);
|
||||
ContentService.SaveAndPublish(content);
|
||||
ContentService.SaveAndPublish(content);
|
||||
// At this point content has 5 versions, 3 historic versions, a draft version and a published version.
|
||||
|
||||
var allVersions = ContentService.GetVersions(content.Id);
|
||||
Debug.Assert(allVersions.Count() == 5); // Sanity check
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
scope.Database.Update<ContentVersionDto>("set preventCleanup = 1 where id in (1,3)");
|
||||
|
||||
var sut = new DocumentVersionRepository(ScopeAccessor);
|
||||
var results = sut.GetDocumentVersionsEligibleForCleanup();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(1, results.Count);
|
||||
|
||||
// We pinned 1 & 3
|
||||
// 4 is current
|
||||
// 5 is published
|
||||
// So all that is left is 2
|
||||
Assert.AreEqual(2, results.First().VersionId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteVersions_Always_DeletesSpecifiedVersions()
|
||||
{
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateId: template.Id);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var content = ContentBuilder.CreateSimpleContent(contentType);
|
||||
|
||||
ContentService.SaveAndPublish(content);
|
||||
ContentService.SaveAndPublish(content);
|
||||
ContentService.SaveAndPublish(content);
|
||||
ContentService.SaveAndPublish(content);
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
var query = scope.SqlContext.Sql();
|
||||
|
||||
query.Select<ContentVersionDto>()
|
||||
.From<ContentVersionDto>();
|
||||
|
||||
var sut = new DocumentVersionRepository(ScopeAccessor);
|
||||
sut.DeleteVersions(new []{1,2,3});
|
||||
|
||||
var after = scope.Database.Fetch<ContentVersionDto>(query);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(2, after.Count);
|
||||
Assert.True(after.All(x => x.Id > 3));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void GetPagedItemsByContentId_WithInvariantCultureContent_ReturnsPaginatedResults()
|
||||
{
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateId: template.Id);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var content = ContentBuilder.CreateSimpleContent(contentType);
|
||||
|
||||
ContentService.SaveAndPublish(content); // Draft + Published
|
||||
ContentService.SaveAndPublish(content); // New Draft
|
||||
|
||||
using (ScopeProvider.CreateScope())
|
||||
{
|
||||
var sut = new DocumentVersionRepository((IScopeAccessor)ScopeProvider);
|
||||
var page1 = sut.GetPagedItemsByContentId(content.Id, 0, 2, out var page1Total);
|
||||
var page2 = sut.GetPagedItemsByContentId(content.Id, 1, 2, out var page2Total);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(2, page1.Count());
|
||||
Assert.AreEqual(3, page1Total);
|
||||
|
||||
Assert.AreEqual(1, page2.Count());
|
||||
Assert.AreEqual(3, page2Total);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPagedItemsByContentId_WithVariantCultureContent_ReturnsPaginatedResults()
|
||||
{
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateId: template.Id);
|
||||
contentType.Variations = ContentVariation.Culture;
|
||||
foreach (var propertyType in contentType.PropertyTypes)
|
||||
{
|
||||
propertyType.Variations = ContentVariation.Culture;
|
||||
}
|
||||
FileService.SaveTemplate(contentType.DefaultTemplate);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var content = ContentBuilder.CreateSimpleContent(contentType, "foo", culture:"en-US");
|
||||
content.SetCultureName("foo", "en-US");
|
||||
|
||||
ContentService.SaveAndPublish(content, "en-US"); // Draft + Published
|
||||
ContentService.SaveAndPublish(content, "en-US"); // New Draft
|
||||
|
||||
using (ScopeProvider.CreateScope())
|
||||
{
|
||||
var sut = new DocumentVersionRepository((IScopeAccessor)ScopeProvider);
|
||||
var page1 = sut.GetPagedItemsByContentId(content.Id, 0, 2, out var page1Total, 1);
|
||||
var page2 = sut.GetPagedItemsByContentId(content.Id, 1, 2, out var page2Total, 1);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(2, page1.Count());
|
||||
Assert.AreEqual(3, page1Total);
|
||||
|
||||
Assert.AreEqual(1, page2.Count());
|
||||
Assert.AreEqual(3, page2Total);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,10 +38,11 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
private IHostingEnvironment HostingEnvironment => GetRequiredService<IHostingEnvironment>();
|
||||
|
||||
private FileSystems FileSystems => GetRequiredService<FileSystems>();
|
||||
private IViewHelper ViewHelper => GetRequiredService<IViewHelper>();
|
||||
|
||||
private ITemplateRepository CreateRepository(IScopeProvider provider) =>
|
||||
new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<TemplateRepository>(), FileSystems, IOHelper, ShortStringHelper);
|
||||
|
||||
new TemplateRepository((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<TemplateRepository>(), FileSystems, IOHelper, ShortStringHelper, ViewHelper);
|
||||
|
||||
[Test]
|
||||
public void Can_Instantiate_Repository()
|
||||
{
|
||||
@@ -90,16 +91,14 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
// Act
|
||||
var template = new Template(ShortStringHelper, "test", "test")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template);
|
||||
|
||||
// Assert
|
||||
Assert.That(repository.Get("test"), Is.Not.Null);
|
||||
Assert.That(FileSystems.MvcViewsFileSystem.FileExists("test.cshtml"), Is.True);
|
||||
Assert.AreEqual(
|
||||
@"@usingUmbraco.Cms.Web.Common.PublishedModels;@inheritsUmbraco.Cms.Web.Common.Views.UmbracoViewPage@{Layout=null;}".StripWhitespace(),
|
||||
template.Content.StripWhitespace());
|
||||
Assert.AreEqual("mock-content", template.Content.StripWhitespace());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +143,13 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
// Act
|
||||
var template = new Template(ShortStringHelper, "test", "test")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template);
|
||||
|
||||
var template2 = new Template(ShortStringHelper, "test", "test")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template2);
|
||||
|
||||
@@ -172,13 +171,13 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
// Act
|
||||
var template = new Template(ShortStringHelper, "test", "test")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template);
|
||||
|
||||
var template2 = new Template(ShortStringHelper, "test1", "test1")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template2);
|
||||
|
||||
@@ -205,7 +204,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
// Act
|
||||
var template = new Template(ShortStringHelper, "test", "test")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template);
|
||||
|
||||
@@ -216,7 +215,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
|
||||
// Assert
|
||||
Assert.That(FileSystems.MvcViewsFileSystem.FileExists("test.cshtml"), Is.True);
|
||||
Assert.That(updated.Content, Is.EqualTo(ViewHelper.GetDefaultFileContent() + "<html></html>"));
|
||||
Assert.That(updated.Content, Is.EqualTo("mock-content" + "<html></html>"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +231,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence.Repos
|
||||
|
||||
var template = new Template(ShortStringHelper, "test", "test")
|
||||
{
|
||||
Content = ViewHelper.GetDefaultFileContent()
|
||||
Content = "mock-content"
|
||||
};
|
||||
repository.Save(template);
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.DependencyInjection;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Tests.Scoping
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class ScopedNuCacheTests : UmbracoIntegrationTest
|
||||
{
|
||||
private IContentService ContentService => GetRequiredService<IContentService>();
|
||||
private Mock<IHttpContextAccessor> MockHttpContextAccessor { get; set; } = CreateMockHttpContextAccessor();
|
||||
private IUmbracoContextFactory UmbracoContextFactory => GetRequiredService<IUmbracoContextFactory>();
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
private IVariationContextAccessor VariationContextAccessor => GetRequiredService<IVariationContextAccessor>();
|
||||
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder)
|
||||
{
|
||||
NotificationHandler.PublishedContent = notification => { };
|
||||
builder.Services.AddUnique<IServerMessenger, ScopedRepositoryTests.LocalServerMessenger>();
|
||||
builder.AddCoreNotifications();
|
||||
builder.AddNotificationHandler<ContentPublishedNotification, NotificationHandler>();
|
||||
builder.Services.AddUnique<IUmbracoContextAccessor, TestUmbracoContextAccessor>();
|
||||
builder.Services.AddUnique<IHttpContextAccessor>(MockHttpContextAccessor.Object);
|
||||
builder.AddNuCache();
|
||||
}
|
||||
|
||||
public class NotificationHandler : INotificationHandler<ContentPublishedNotification>
|
||||
{
|
||||
public void Handle(ContentPublishedNotification notification) => PublishedContent?.Invoke(notification);
|
||||
|
||||
public static Action<ContentPublishedNotification> PublishedContent { get; set; }
|
||||
}
|
||||
|
||||
private static Mock<IHttpContextAccessor> CreateMockHttpContextAccessor()
|
||||
{
|
||||
var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.Scheme = "http";
|
||||
httpContext.Request.Host = new HostString("localhost");
|
||||
|
||||
mockHttpContextAccessor.SetupGet(x => x.HttpContext).Returns(httpContext);
|
||||
return mockHttpContextAccessor;
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestScope(bool complete)
|
||||
{
|
||||
var umbracoContext = UmbracoContextFactory.EnsureUmbracoContext().UmbracoContext;
|
||||
|
||||
// create document type, document
|
||||
var contentType = new ContentType(ShortStringHelper, -1) { Alias = "CustomDocument", Name = "Custom Document" };
|
||||
ContentTypeService.Save(contentType);
|
||||
var item = new Content("name", -1, contentType);
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
ContentService.SaveAndPublish(item);
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// event handler
|
||||
var evented = 0;
|
||||
NotificationHandler.PublishedContent = notification =>
|
||||
{
|
||||
evented++;
|
||||
|
||||
var e = umbracoContext.Content.GetById(item.Id);
|
||||
|
||||
// during events, due to LiveSnapshot, we see the changes
|
||||
Assert.IsNotNull(e);
|
||||
Assert.AreEqual("changed", e.Name(VariationContextAccessor));
|
||||
};
|
||||
|
||||
// been created
|
||||
var x = umbracoContext.Content.GetById(item.Id);
|
||||
Assert.IsNotNull(x);
|
||||
Assert.AreEqual("name", x.Name(VariationContextAccessor));
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
{
|
||||
item.Name = "changed";
|
||||
ContentService.SaveAndPublish(item);
|
||||
|
||||
if (complete)
|
||||
{
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
// only 1 event occuring because we are publishing twice for the same event for
|
||||
// the same object and the scope deduplicates the events (uses the latest)
|
||||
Assert.AreEqual(complete ? 1 : 0, evented);
|
||||
|
||||
// after the scope,
|
||||
// if completed, we see the changes
|
||||
// else changes have been rolled back
|
||||
x = umbracoContext.Content.GetById(item.Id);
|
||||
Assert.IsNotNull(x);
|
||||
Assert.AreEqual(complete ? "changed" : "name", x.Name(VariationContextAccessor));
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,27 +3,26 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using NPoco;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping;
|
||||
using Umbraco.Extensions;
|
||||
using Language = Umbraco.Cms.Core.Models.Language;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
{
|
||||
@@ -52,9 +51,14 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder)
|
||||
{
|
||||
InMemoryConfiguration[Constants.Configuration.ConfigNuCache + ":" + nameof(NuCacheSettings.NuCacheSerializerType)] = NuCacheSerializerType.JSON.ToString();
|
||||
builder.AddNuCache();
|
||||
builder.Services.AddUnique<IServerMessenger, ScopedRepositoryTests.LocalServerMessenger>();
|
||||
builder.Services.PostConfigure<NuCacheSettings>(options =>
|
||||
{
|
||||
options.NuCacheSerializerType = NuCacheSerializerType.JSON;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void AssertJsonStartsWith(int id, string expected)
|
||||
@@ -1333,7 +1337,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
{
|
||||
Alias = alias,
|
||||
Name = alias,
|
||||
Variations = variance
|
||||
Variations = variance,
|
||||
};
|
||||
|
||||
private PropertyTypeCollection CreatePropertyCollection(params (string alias, ContentVariation variance)[] props)
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
internal class ContentVersionCleanupServiceTest : UmbracoIntegrationTest
|
||||
{
|
||||
public IFileService FileService => GetRequiredService<IFileService>();
|
||||
|
||||
public IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
public IContentService ContentService => GetRequiredService<IContentService>();
|
||||
|
||||
public IContentVersionService ContentVersionService => GetRequiredService<IContentVersionService>();
|
||||
|
||||
/// <remarks>
|
||||
/// This is covered by the unit tests, but nice to know it deletes on infra.
|
||||
/// And proves implementation is compatible with SQL CE.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
public void PerformContentVersionCleanup_WithNoKeepPeriods_DeletesEverythingExceptActive()
|
||||
{
|
||||
// For reference, Our currently has
|
||||
// 5000 Documents
|
||||
// With 200K Versions
|
||||
// With 11M Property data
|
||||
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
ContentType contentTypeA = ContentTypeBuilder.CreateSimpleContentType("contentTypeA", "contentTypeA", defaultTemplateId: template.Id);
|
||||
|
||||
// Kill all historic
|
||||
contentTypeA.HistoryCleanup.PreventCleanup = false;
|
||||
contentTypeA.HistoryCleanup.KeepAllVersionsNewerThanDays = 0;
|
||||
contentTypeA.HistoryCleanup.KeepLatestVersionPerDayForDays = 0;
|
||||
|
||||
ContentTypeService.Save(contentTypeA);
|
||||
|
||||
Content content = ContentBuilder.CreateSimpleContent(contentTypeA);
|
||||
ContentService.SaveAndPublish(content);
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
ContentService.SaveAndPublish(content);
|
||||
}
|
||||
|
||||
Report before = GetReport();
|
||||
|
||||
Debug.Assert(before.ContentVersions == 12); // 10 historic + current draft + current published
|
||||
Debug.Assert(before.PropertyData == 12 * 3); // CreateSimpleContentType = 3 props
|
||||
|
||||
ContentVersionService.PerformContentVersionCleanup(DateTime.Now.AddHours(1));
|
||||
|
||||
Report after = GetReport();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(2, after.ContentVersions); // current draft, current published
|
||||
Assert.AreEqual(2, after.DocumentVersions);
|
||||
Assert.AreEqual(6, after.PropertyData); // CreateSimpleContentType = 3 props
|
||||
});
|
||||
}
|
||||
|
||||
private Report GetReport()
|
||||
{
|
||||
using (IScope scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
// SQL CE is fun!
|
||||
var contentVersions = scope.Database.Single<int>(@"select count(1) from umbracoContentVersion");
|
||||
var documentVersions = scope.Database.Single<int>(@"select count(1) from umbracoDocumentVersion");
|
||||
var propertyData = scope.Database.Single<int>(@"select count(1) from umbracoPropertyData");
|
||||
|
||||
return new Report
|
||||
{
|
||||
ContentVersions = contentVersions,
|
||||
DocumentVersions = documentVersions,
|
||||
PropertyData = propertyData
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertCleanupPolicy(IContentType contentType, int daysToKeepAll, int daysToRollupAll, bool preventCleanup = false)
|
||||
{
|
||||
using (IScope scope = ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
var entity = new ContentVersionCleanupPolicyDto
|
||||
{
|
||||
ContentTypeId = contentType.Id,
|
||||
KeepAllVersionsNewerThanDays = daysToKeepAll,
|
||||
KeepLatestVersionPerDayForDays = daysToRollupAll,
|
||||
PreventCleanup = preventCleanup,
|
||||
Updated = DateTime.Today
|
||||
};
|
||||
|
||||
scope.Database.Insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private class Report
|
||||
{
|
||||
public int ContentVersions { get; set; }
|
||||
|
||||
public int DocumentVersions { get; set; }
|
||||
|
||||
public int PropertyData { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,13 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
@@ -14,6 +20,13 @@ using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services.Importing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Media;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
{
|
||||
@@ -22,6 +35,14 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
public class EntityXmlSerializerTests : UmbracoIntegrationTest
|
||||
{
|
||||
private IEntityXmlSerializer Serializer => GetRequiredService<IEntityXmlSerializer>();
|
||||
private IContentService ContentService => GetRequiredService<IContentService>();
|
||||
private IMediaService MediaService => GetRequiredService<IMediaService>();
|
||||
private IUserService UserService => GetRequiredService<IUserService>();
|
||||
private IMediaTypeService MediaTypeService => GetRequiredService<IMediaTypeService>();
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
private IDataValueEditorFactory DataValueEditorFactory => GetRequiredService<IDataValueEditorFactory>();
|
||||
private ILocalizedTextService TextService => GetRequiredService<ILocalizedTextService>();
|
||||
private IFileService FileService => GetRequiredService<IFileService>();
|
||||
|
||||
[Test]
|
||||
public void Can_Export_Macro()
|
||||
@@ -89,6 +110,175 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
Assert.That(xml.ToString(), Is.EqualTo(languageItemsElement.ToString()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Generate_Xml_Representation_Of_Content()
|
||||
{
|
||||
// Arrange
|
||||
var template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template); // else, FK violation on contentType!
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(
|
||||
defaultTemplateId: template.Id);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var content = ContentBuilder.CreateTextpageContent(contentType, "Root Home", -1);
|
||||
ContentService.Save(content, Constants.Security.SuperUserId);
|
||||
|
||||
var nodeName = content.ContentType.Alias.ToSafeAlias(ShortStringHelper);
|
||||
var urlName = content.GetUrlSegment(ShortStringHelper, new[] { new DefaultUrlSegmentProvider(ShortStringHelper) });
|
||||
|
||||
// Act
|
||||
XElement element = content.ToXml(Serializer);
|
||||
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.Name.LocalName, Is.EqualTo(nodeName));
|
||||
Assert.AreEqual(content.Id.ToString(), (string)element.Attribute("id"));
|
||||
Assert.AreEqual(content.ParentId.ToString(), (string)element.Attribute("parentID"));
|
||||
Assert.AreEqual(content.Level.ToString(), (string)element.Attribute("level"));
|
||||
Assert.AreEqual(content.CreatorId.ToString(), (string)element.Attribute("creatorID"));
|
||||
Assert.AreEqual(content.SortOrder.ToString(), (string)element.Attribute("sortOrder"));
|
||||
Assert.AreEqual(content.CreateDate.ToString("s"), (string)element.Attribute("createDate"));
|
||||
Assert.AreEqual(content.UpdateDate.ToString("s"), (string)element.Attribute("updateDate"));
|
||||
Assert.AreEqual(content.Name, (string)element.Attribute("nodeName"));
|
||||
Assert.AreEqual(urlName, (string)element.Attribute("urlName"));
|
||||
Assert.AreEqual(content.Path, (string)element.Attribute("path"));
|
||||
Assert.AreEqual("", (string)element.Attribute("isDoc"));
|
||||
Assert.AreEqual(content.ContentType.Id.ToString(), (string)element.Attribute("nodeType"));
|
||||
Assert.AreEqual(content.GetCreatorProfile(UserService).Name, (string)element.Attribute("creatorName"));
|
||||
Assert.AreEqual(content.GetWriterProfile(UserService).Name, (string)element.Attribute("writerName"));
|
||||
Assert.AreEqual(content.WriterId.ToString(), (string)element.Attribute("writerID"));
|
||||
Assert.AreEqual(content.TemplateId.ToString(), (string)element.Attribute("template"));
|
||||
|
||||
Assert.AreEqual(content.Properties["title"].GetValue().ToString(), element.Elements("title").Single().Value);
|
||||
Assert.AreEqual(content.Properties["bodyText"].GetValue().ToString(), element.Elements("bodyText").Single().Value);
|
||||
Assert.AreEqual(content.Properties["keywords"].GetValue().ToString(), element.Elements("keywords").Single().Value);
|
||||
Assert.AreEqual(content.Properties["description"].GetValue().ToString(), element.Elements("description").Single().Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Generate_Xml_Representation_Of_Media()
|
||||
{
|
||||
// Arrange
|
||||
var mediaType = MediaTypeBuilder.CreateImageMediaType("image2");
|
||||
|
||||
MediaTypeService.Save(mediaType);
|
||||
|
||||
// reference, so static ctor runs, so event handlers register
|
||||
// and then, this will reset the width, height... because the file does not exist, of course ;-(
|
||||
var loggerFactory = NullLoggerFactory.Instance;
|
||||
var scheme = Mock.Of<IMediaPathScheme>();
|
||||
var contentSettings = new ContentSettings();
|
||||
|
||||
var mediaFileManager = new MediaFileManager(
|
||||
Mock.Of<IFileSystem>(),
|
||||
scheme,
|
||||
loggerFactory.CreateLogger<MediaFileManager>(),
|
||||
ShortStringHelper,
|
||||
Services,
|
||||
Options.Create(new ContentSettings()));
|
||||
|
||||
var ignored = new FileUploadPropertyEditor(
|
||||
DataValueEditorFactory,
|
||||
mediaFileManager,
|
||||
Options.Create(contentSettings),
|
||||
TextService,
|
||||
Services.GetRequiredService<UploadAutoFillProperties>(),
|
||||
ContentService,
|
||||
IOHelper);
|
||||
|
||||
var media = MediaBuilder.CreateMediaImage(mediaType, -1);
|
||||
media.WriterId = -1; // else it's zero and that's not a user and it breaks the tests
|
||||
MediaService.Save(media, Constants.Security.SuperUserId);
|
||||
|
||||
// so we have to force-reset these values because the property editor has cleared them
|
||||
media.SetValue(Constants.Conventions.Media.Width, "200");
|
||||
media.SetValue(Constants.Conventions.Media.Height, "200");
|
||||
media.SetValue(Constants.Conventions.Media.Bytes, "100");
|
||||
media.SetValue(Constants.Conventions.Media.Extension, "png");
|
||||
|
||||
var nodeName = media.ContentType.Alias.ToSafeAlias(ShortStringHelper);
|
||||
var urlName = media.GetUrlSegment(ShortStringHelper, new[] { new DefaultUrlSegmentProvider(ShortStringHelper) });
|
||||
|
||||
// Act
|
||||
XElement element = media.ToXml(Serializer);
|
||||
|
||||
// Assert
|
||||
Assert.That(element, Is.Not.Null);
|
||||
Assert.That(element.Name.LocalName, Is.EqualTo(nodeName));
|
||||
Assert.AreEqual(media.Id.ToString(), (string)element.Attribute("id"));
|
||||
Assert.AreEqual(media.ParentId.ToString(), (string)element.Attribute("parentID"));
|
||||
Assert.AreEqual(media.Level.ToString(), (string)element.Attribute("level"));
|
||||
Assert.AreEqual(media.SortOrder.ToString(), (string)element.Attribute("sortOrder"));
|
||||
Assert.AreEqual(media.CreateDate.ToString("s"), (string)element.Attribute("createDate"));
|
||||
Assert.AreEqual(media.UpdateDate.ToString("s"), (string)element.Attribute("updateDate"));
|
||||
Assert.AreEqual(media.Name, (string)element.Attribute("nodeName"));
|
||||
Assert.AreEqual(urlName, (string)element.Attribute("urlName"));
|
||||
Assert.AreEqual(media.Path, (string)element.Attribute("path"));
|
||||
Assert.AreEqual("", (string)element.Attribute("isDoc"));
|
||||
Assert.AreEqual(media.ContentType.Id.ToString(), (string)element.Attribute("nodeType"));
|
||||
Assert.AreEqual(media.GetCreatorProfile(UserService).Name, (string)element.Attribute("writerName"));
|
||||
Assert.AreEqual(media.CreatorId.ToString(), (string)element.Attribute("writerID"));
|
||||
Assert.IsNull(element.Attribute("template"));
|
||||
|
||||
Assert.AreEqual(media.Properties[Constants.Conventions.Media.File].GetValue().ToString(), element.Elements(Constants.Conventions.Media.File).Single().Value);
|
||||
Assert.AreEqual(media.Properties[Constants.Conventions.Media.Width].GetValue().ToString(), element.Elements(Constants.Conventions.Media.Width).Single().Value);
|
||||
Assert.AreEqual(media.Properties[Constants.Conventions.Media.Height].GetValue().ToString(), element.Elements(Constants.Conventions.Media.Height).Single().Value);
|
||||
Assert.AreEqual(media.Properties[Constants.Conventions.Media.Bytes].GetValue().ToString(), element.Elements(Constants.Conventions.Media.Bytes).Single().Value);
|
||||
Assert.AreEqual(media.Properties[Constants.Conventions.Media.Extension].GetValue().ToString(), element.Elements(Constants.Conventions.Media.Extension).Single().Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Serialize_ForContentTypeWithHistoryCleanupPolicy_OutputsSerializedHistoryCleanupPolicy()
|
||||
{
|
||||
// Arrange
|
||||
var template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template); // else, FK violation on contentType!
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id);
|
||||
|
||||
contentType.HistoryCleanup = new HistoryCleanup
|
||||
{
|
||||
PreventCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 1,
|
||||
KeepLatestVersionPerDayForDays = 2
|
||||
};
|
||||
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
// Act
|
||||
var element = Serializer.Serialize(contentType);
|
||||
|
||||
// Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(element.Element("HistoryCleanupPolicy")!.Attribute("preventCleanup")!.Value, Is.EqualTo("true"));
|
||||
Assert.That(element.Element("HistoryCleanupPolicy")!.Attribute("keepAllVersionsNewerThanDays")!.Value, Is.EqualTo("1"));
|
||||
Assert.That(element.Element("HistoryCleanupPolicy")!.Attribute("keepLatestVersionPerDayForDays")!.Value, Is.EqualTo("2"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Serialize_ForContentTypeWithNullHistoryCleanupPolicy_DoesNotOutputSerializedDefaultPolicy()
|
||||
{
|
||||
// Arrange
|
||||
var template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template); // else, FK violation on contentType!
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id);
|
||||
|
||||
contentType.HistoryCleanup = null;
|
||||
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var element = Serializer.Serialize(contentType);
|
||||
|
||||
// Assert
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(element.Element("HistoryCleanupPolicy"), Is.Null);
|
||||
});
|
||||
}
|
||||
|
||||
private void CreateDictionaryData()
|
||||
{
|
||||
ILocalizationService localizationService = GetRequiredService<ILocalizationService>();
|
||||
@@ -104,7 +294,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
.Build();
|
||||
localizationService.Save(languageEnGb);
|
||||
|
||||
var parentItem = new DictionaryItem("Parent") {Key = Guid.Parse("28f2e02a-8c66-4fcd-85e3-8524d551c0d3")};
|
||||
var parentItem = new DictionaryItem("Parent") { Key = Guid.Parse("28f2e02a-8c66-4fcd-85e3-8524d551c0d3") };
|
||||
var parentTranslations = new List<IDictionaryTranslation>
|
||||
{
|
||||
new DictionaryTranslation(languageNbNo, "ForelderVerdi"),
|
||||
@@ -113,7 +303,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
parentItem.Translations = parentTranslations;
|
||||
localizationService.Save(parentItem);
|
||||
|
||||
var childItem = new DictionaryItem(parentItem.Key, "Child"){Key = Guid.Parse("e7dba0a9-d517-4ba4-8e18-2764d392c611")};
|
||||
var childItem = new DictionaryItem(parentItem.Key, "Child") { Key = Guid.Parse("e7dba0a9-d517-4ba4-8e18-2764d392c611") };
|
||||
var childTranslations = new List<IDictionaryTranslation>
|
||||
{
|
||||
new DictionaryTranslation(languageNbNo, "BarnVerdi"),
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services.Importin
|
||||
/// </info>
|
||||
/// <Documents>
|
||||
/// <DocumentSet importMode="root">
|
||||
/// <NewType id="1148" parentID="-1" level="1" creatorID="0" sortOrder="9" createDate="2013-07-23T12:06:07" updateDate="2013-07-23T15:56:37" nodeName="DoIt" urlName="doit" path="-1,1148" isDoc="" nodeType="1134" creatorName="admin" writerName="admin" writerID="0" template="1133" nodeTy [rest of string was truncated]";.
|
||||
/// <NewType key="9c9b55d0-2fbf-4f12-afea-023bd7b2519d" id="1148" parentID="-1" level="1" creatorID="0" sortOrder="9" createDate="2013-07-23T12:06:07" updateDate="2013-07-23T15:56:37" nodeName="DoIt" urlName="doit" path="-1,1148" isDoc="" nodeType="1134" creatorName="admin" writerName= [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string CheckboxList_Content_Package {
|
||||
get {
|
||||
@@ -91,7 +91,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services.Importin
|
||||
/// </info>
|
||||
/// <Documents>
|
||||
/// <DocumentSet importMode="root">
|
||||
/// <umbHomePage id="1068" parentID="-1" level="1" creatorID="0" sortOrder="0" createDate="2014-11-26T12:52:35" updateDate="2014-11-26T12:52:36" nodeName="Home" urlName="home" path="-1,1068" isDoc="" nodeType="1056" creatorName="Morten Christensen" writerName="Morten Christensen" [rest of string was truncated]";.
|
||||
/// <umbHomePage key="9c9b55d0-2fbf-4f12-afea-023bd7b2519d" id="1068" parentID="-1" level="1" creatorID="0" sortOrder="0" createDate="2014-11-26T12:52:35" updateDate="2014-11-26T12:52:36" nodeName="Home" urlName="home" path="-1,1068" isDoc="" nodeType="1056" creatorName="Morten Ch [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string CompositionsTestPackage {
|
||||
get {
|
||||
@@ -124,15 +124,14 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services.Importin
|
||||
/// <files />
|
||||
/// <info>
|
||||
/// <package>
|
||||
/// <name>Dictionary-Package</name>
|
||||
/// <name>Dictionary-Package</name>
|
||||
/// </package>
|
||||
/// </info>
|
||||
/// <DictionaryItems>
|
||||
/// <DictionaryItem Key="Parent">
|
||||
/// <DictionaryItem Key="28f2e02a-8c66-4fcd-85e3-8524d551c0d3" Name="Parent">
|
||||
/// <Value LanguageId="2" LanguageCultureAlias="nb-NO"><![CDATA[ForelderVerdi]]></Value>
|
||||
/// <Value LanguageId="3" LanguageCultureAlias="en-GB"><![CDATA[ParentValue]]></Value>
|
||||
/// <DictionaryItem Key="Child">
|
||||
/// <Value LanguageId="2" LanguageCultureAlias="nb-NO"><![CDATA[BarnV [rest of string was truncated]";.
|
||||
/// <DictionaryItem Key="e7dba0a9-d517-4ba4-8e18-2764d392c611" Name=" [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string Dictionary_Package {
|
||||
get {
|
||||
@@ -239,6 +238,33 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services.Importin
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8" ?>
|
||||
///<DocumentType>
|
||||
/// <Info>
|
||||
/// <Name>test</Name>
|
||||
/// <Key>150ead17-d359-42a2-ac33-6504cc52ced1</Key>
|
||||
/// <Alias>test</Alias>
|
||||
/// <Icon>folder.gif</Icon>
|
||||
/// <Thumbnail>folder.png</Thumbnail>
|
||||
/// <Description>
|
||||
/// </Description>
|
||||
/// <AllowAtRoot>False</AllowAtRoot>
|
||||
/// <AllowedTemplates>
|
||||
/// <Template>test</Template>
|
||||
/// </AllowedTemplates>
|
||||
/// <DefaultTemplate>test</DefaultTemplate>
|
||||
/// </Info>
|
||||
/// <Structure>
|
||||
/// <DocumentType>test</DocumentType>
|
||||
/// </Str [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string SingleDocType_WithCleanupPolicy {
|
||||
get {
|
||||
return ResourceManager.GetString("SingleDocType_WithCleanupPolicy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
///<umbPackage>
|
||||
@@ -249,8 +275,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services.Importin
|
||||
/// </info>
|
||||
/// <Documents>
|
||||
/// <DocumentSet importMode="root">
|
||||
/// <Homepage id="1072" parentID="-1" level="1" creatorID="0" sortOrder="0" createDate="2013-02-17T09:04:39" updateDate="2013-02-17T09:10:47" nodeName="Home" urlName="home" path="-1,1072" isDoc="" nodeType="1062" creatorName="admin" writerName="admin" writerID="0" template="1049">
|
||||
/// <slide [rest of string was truncated]";.
|
||||
/// <Homepage key="9c9b55d0-2fbf-4f12-afea-023bd7b2519d" id="1072" parentID="-1" level="1" creatorID="0" sortOrder="0" createDate="2013-02-17T09:04:39" updateDate="2013-02-17T09:10:47" nodeName="Home" urlName="home" path="-1,1072" isDoc="" nodeType="1062" creatorName="admin" writerName="admin" wr [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string StandardMvc_Package {
|
||||
get {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,36 +26,36 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
@@ -157,4 +157,7 @@
|
||||
<data name="MediaTypesAndMedia_Package.xml" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>MediaTypesAndMedia-Package.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="SingleDocType_WithCleanupPolicy" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>SingleDocType-WithCleanupPolicy.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<DocumentType>
|
||||
<Info>
|
||||
<Name>test</Name>
|
||||
<Key>150ead17-d359-42a2-ac33-6504cc52ced1</Key>
|
||||
<Alias>test</Alias>
|
||||
<Icon>folder.gif</Icon>
|
||||
<Thumbnail>folder.png</Thumbnail>
|
||||
<Description>
|
||||
</Description>
|
||||
<AllowAtRoot>False</AllowAtRoot>
|
||||
<AllowedTemplates>
|
||||
<Template>test</Template>
|
||||
</AllowedTemplates>
|
||||
<DefaultTemplate>test</DefaultTemplate>
|
||||
</Info>
|
||||
<Structure>
|
||||
<DocumentType>test</DocumentType>
|
||||
</Structure>
|
||||
<GenericProperties>
|
||||
<GenericProperty>
|
||||
<Name>test</Name>
|
||||
<Alias>test</Alias>
|
||||
<Type>b4471851-82b6-4c75-afa4-39fa9c6a75e9</Type>
|
||||
<Definition>fbaf13a8-4036-41f2-93a3-974f678c312a</Definition>
|
||||
<Tab>
|
||||
</Tab>
|
||||
<Mandatory>False</Mandatory>
|
||||
<Validation>
|
||||
</Validation>
|
||||
<Description><![CDATA[]]></Description>
|
||||
</GenericProperty>
|
||||
</GenericProperties>
|
||||
<Tabs />
|
||||
<HistoryCleanupPolicy preventCleanup="true" keepAllVersionsNewerThanDays="1" keepLatestVersionPerDayForDays="2" />
|
||||
</DocumentType>
|
||||
@@ -0,0 +1,87 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true, WithApplication = true)]
|
||||
public class NuCacheRebuildTests : UmbracoIntegrationTest
|
||||
{
|
||||
private IFileService FileService => GetRequiredService<IFileService>();
|
||||
|
||||
private IContentService ContentService => GetRequiredService<IContentService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private IPublishedSnapshotService PublishedSnapshotService => GetRequiredService<IPublishedSnapshotService>();
|
||||
|
||||
[Test]
|
||||
public void UnpublishedNameChanges()
|
||||
{
|
||||
var urlSegmentProvider = new DefaultUrlSegmentProvider(ShortStringHelper);
|
||||
|
||||
Template template = TemplateBuilder.CreateTextPageTemplate();
|
||||
FileService.SaveTemplate(template);
|
||||
|
||||
ContentType contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id);
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
Content content = ContentBuilder.CreateTextpageContent(contentType, "hello", Constants.System.Root);
|
||||
|
||||
ContentService.SaveAndPublish(content);
|
||||
IContent cachedContent = ContentService.GetById(content.Id);
|
||||
var segment = urlSegmentProvider.GetUrlSegment(cachedContent);
|
||||
|
||||
// Does a new node work?
|
||||
|
||||
Assert.AreEqual("hello", segment);
|
||||
|
||||
content.Name = "goodbye";
|
||||
cachedContent = ContentService.GetById(content.Id);
|
||||
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
|
||||
|
||||
// We didn't save anything, so all should still be the same
|
||||
|
||||
Assert.AreEqual("hello", segment);
|
||||
|
||||
ContentService.Save(content);
|
||||
cachedContent = ContentService.GetById(content.Id);
|
||||
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
|
||||
|
||||
// At this point we have saved the new name, but not published. The url should still be the previous name
|
||||
|
||||
Assert.AreEqual("hello", segment);
|
||||
|
||||
PublishedSnapshotService.Rebuild();
|
||||
|
||||
cachedContent = ContentService.GetById(content.Id);
|
||||
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
|
||||
|
||||
// After a rebuild, the unpublished name should still not be the url.
|
||||
// This was previously incorrect, per #11074
|
||||
|
||||
Assert.AreEqual("hello", segment);
|
||||
|
||||
ContentService.SaveAndPublish(content);
|
||||
cachedContent = ContentService.GetById(content.Id);
|
||||
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
|
||||
|
||||
// The page has now been published, so we should see the new url segment
|
||||
Assert.AreEqual("goodbye", segment);
|
||||
|
||||
PublishedSnapshotService.Rebuild();
|
||||
cachedContent = ContentService.GetById(content.Id);
|
||||
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
|
||||
|
||||
// Just double checking that things remain after a rebuild
|
||||
Assert.AreEqual("goodbye", segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
@@ -10,7 +10,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(OS)' == 'Windows_NT'">
|
||||
<PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.6" />
|
||||
<RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -52,6 +51,8 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>ImportResources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Remove="Umbraco.Web.BackOffice\UrlAndDomains\package.xml" />
|
||||
<EmbeddedResource Include="Umbraco.Web.BackOffice\UrlAndDomains\package.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -79,10 +80,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Examine.Lucene" Version="2.0.0" />
|
||||
<PackageReference Include="Bogus" Version="33.1.1" />
|
||||
<PackageReference Include="Examine.Lucene" Version="2.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.10" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.9" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0">
|
||||
@@ -99,7 +102,6 @@
|
||||
<ProjectReference Include="..\..\src\Umbraco.PublishedCache.NuCache\Umbraco.PublishedCache.NuCache.csproj" />
|
||||
<ProjectReference Include="..\Umbraco.Tests.Common\Umbraco.Tests.Common.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Web.BackOffice\Umbraco.Web.BackOffice.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" />
|
||||
<ProjectReference Include="..\..\src\Umbraco.Web.Website\Umbraco.Web.Website.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Integration.TestServerTest;
|
||||
using Umbraco.Cms.Web.BackOffice.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Formatters;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.BackOffice.Controllers
|
||||
{
|
||||
[TestFixture]
|
||||
public class EntityControllerTests : UmbracoTestServerTestBase
|
||||
{
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_MediaWithIntegerIds_ReturnsValidMap()
|
||||
{
|
||||
IMediaTypeService mediaTypeService = Services.GetRequiredService<IMediaTypeService>();
|
||||
IMediaService mediaService = Services.GetRequiredService<IMediaService>();
|
||||
|
||||
var mediaItems = new List<Media>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IMediaType mediaType = mediaTypeService.Get("image");
|
||||
mediaTypeService.Save(mediaType);
|
||||
|
||||
mediaItems.Add(MediaBuilder.CreateMediaImage(mediaType, -1));
|
||||
mediaItems.Add(MediaBuilder.CreateMediaImage(mediaType, -1));
|
||||
|
||||
foreach (Media media in mediaItems)
|
||||
{
|
||||
mediaService.Save(media);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Media
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
mediaItems[0].Id,
|
||||
mediaItems[1].Id,
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<int, string> results = await response.Content.ReadFromJsonAsync<IDictionary<int, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.IsTrue(results![payload.ids[0]].StartsWith("/media"));
|
||||
Assert.IsTrue(results![payload.ids[1]].StartsWith("/media"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_Media_ReturnsEmptyStringsInMapForUnknownItems()
|
||||
{
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Media
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[] { 1, 2 }
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<int, string> results = await response.Content.ReadFromJsonAsync<IDictionary<int, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.That(results!.Keys.Count, Is.EqualTo(2));
|
||||
Assert.AreEqual(results![payload.ids[0]], string.Empty);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_MediaWithGuidIds_ReturnsValidMap()
|
||||
{
|
||||
IMediaTypeService mediaTypeService = Services.GetRequiredService<IMediaTypeService>();
|
||||
IMediaService mediaService = Services.GetRequiredService<IMediaService>();
|
||||
|
||||
var mediaItems = new List<Media>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IMediaType mediaType = mediaTypeService.Get("image");
|
||||
mediaTypeService.Save(mediaType);
|
||||
|
||||
mediaItems.Add(MediaBuilder.CreateMediaImage(mediaType, -1));
|
||||
mediaItems.Add(MediaBuilder.CreateMediaImage(mediaType, -1));
|
||||
|
||||
foreach (Media media in mediaItems)
|
||||
{
|
||||
mediaService.Save(media);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Media
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
mediaItems[0].Key.ToString(),
|
||||
mediaItems[1].Key.ToString(),
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<string, string> results = await response.Content.ReadFromJsonAsync<IDictionary<string, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.IsTrue(results![payload.ids[0]].StartsWith("/media"));
|
||||
Assert.IsTrue(results![payload.ids[1]].StartsWith("/media"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_MediaWithUdiIds_ReturnsValidMap()
|
||||
{
|
||||
IMediaTypeService mediaTypeService = Services.GetRequiredService<IMediaTypeService>();
|
||||
IMediaService mediaService = Services.GetRequiredService<IMediaService>();
|
||||
|
||||
var mediaItems = new List<Media>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IMediaType mediaType = mediaTypeService.Get("image");
|
||||
mediaTypeService.Save(mediaType);
|
||||
|
||||
mediaItems.Add(MediaBuilder.CreateMediaImage(mediaType, -1));
|
||||
mediaItems.Add(MediaBuilder.CreateMediaImage(mediaType, -1));
|
||||
|
||||
foreach (Media media in mediaItems)
|
||||
{
|
||||
mediaService.Save(media);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Media
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
mediaItems[0].GetUdi().ToString(),
|
||||
mediaItems[1].GetUdi().ToString(),
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<string, string> results = await response.Content.ReadFromJsonAsync<IDictionary<string, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.IsTrue(results![payload.ids[0]].StartsWith("/media"));
|
||||
Assert.IsTrue(results![payload.ids[1]].StartsWith("/media"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_Documents_ReturnsHashesInMapForUnknownItems()
|
||||
{
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Document
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[] { 1, 2 }
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<int, string> results = await response.Content.ReadFromJsonAsync<IDictionary<int, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.That(results!.Keys.Count, Is.EqualTo(2));
|
||||
Assert.AreEqual(results![payload.ids[0]], "#");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_DocumentWithIntIds_ReturnsValidMap()
|
||||
{
|
||||
IContentTypeService contentTypeService = Services.GetRequiredService<IContentTypeService>();
|
||||
IContentService contentService = Services.GetRequiredService<IContentService>();
|
||||
|
||||
var contentItems = new List<IContent>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IContentType contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
contentTypeService.Save(contentType);
|
||||
|
||||
ContentBuilder builder = new ContentBuilder()
|
||||
.WithContentType(contentType);
|
||||
|
||||
Content root = builder.WithName("foo").Build();
|
||||
contentService.SaveAndPublish(root);
|
||||
|
||||
contentItems.Add(builder.WithParent(root).WithName("bar").Build());
|
||||
contentItems.Add(builder.WithParent(root).WithName("baz").Build());
|
||||
|
||||
foreach (IContent content in contentItems)
|
||||
{
|
||||
contentService.SaveAndPublish(content);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Document
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
contentItems[0].Id,
|
||||
contentItems[1].Id,
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<int, string> results = await response.Content.ReadFromJsonAsync<IDictionary<int, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.IsTrue(results![payload.ids[0]].StartsWith("/bar"));
|
||||
Assert.IsTrue(results![payload.ids[1]].StartsWith("/baz"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_DocumentWithGuidIds_ReturnsValidMap()
|
||||
{
|
||||
IContentTypeService contentTypeService = Services.GetRequiredService<IContentTypeService>();
|
||||
IContentService contentService = Services.GetRequiredService<IContentService>();
|
||||
|
||||
var contentItems = new List<IContent>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IContentType contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
contentTypeService.Save(contentType);
|
||||
|
||||
ContentBuilder builder = new ContentBuilder()
|
||||
.WithContentType(contentType);
|
||||
|
||||
Content root = builder.WithName("foo").Build();
|
||||
contentService.SaveAndPublish(root);
|
||||
|
||||
contentItems.Add(builder.WithParent(root).WithName("bar").Build());
|
||||
contentItems.Add(builder.WithParent(root).WithName("baz").Build());
|
||||
|
||||
foreach (IContent content in contentItems)
|
||||
{
|
||||
contentService.SaveAndPublish(content);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Document
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
contentItems[0].Key.ToString(),
|
||||
contentItems[1].Key.ToString(),
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<string, string> results = await response.Content.ReadFromJsonAsync<IDictionary<string, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.IsTrue(results![payload.ids[0]].StartsWith("/bar"));
|
||||
Assert.IsTrue(results![payload.ids[1]].StartsWith("/baz"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetUrlsByIds_DocumentWithUdiIds_ReturnsValidMap()
|
||||
{
|
||||
IContentTypeService contentTypeService = Services.GetRequiredService<IContentTypeService>();
|
||||
IContentService contentService = Services.GetRequiredService<IContentService>();
|
||||
|
||||
var contentItems = new List<IContent>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IContentType contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
contentTypeService.Save(contentType);
|
||||
|
||||
ContentBuilder builder = new ContentBuilder()
|
||||
.WithContentType(contentType);
|
||||
|
||||
Content root = builder.WithName("foo").Build();
|
||||
contentService.SaveAndPublish(root);
|
||||
|
||||
contentItems.Add(builder.WithParent(root).WithName("bar").Build());
|
||||
contentItems.Add(builder.WithParent(root).WithName("baz").Build());
|
||||
|
||||
foreach (IContent content in contentItems)
|
||||
{
|
||||
contentService.SaveAndPublish(content);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Document
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetUrlsByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var payload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
contentItems[0].GetUdi().ToString(),
|
||||
contentItems[1].GetUdi().ToString(),
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage response = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, payload);
|
||||
|
||||
// skip pointless un-parseable cruft.
|
||||
(await response.Content.ReadAsStreamAsync()).Seek(AngularJsonMediaTypeFormatter.XsrfPrefix.Length, SeekOrigin.Begin);
|
||||
|
||||
IDictionary<string, string> results = await response.Content.ReadFromJsonAsync<IDictionary<string, string>>();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.IsTrue(results![payload.ids[0]].StartsWith("/bar"));
|
||||
Assert.IsTrue(results![payload.ids[1]].StartsWith("/baz"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetByIds_MultipleCalls_WorksAsExpected()
|
||||
{
|
||||
IContentTypeService contentTypeService = Services.GetRequiredService<IContentTypeService>();
|
||||
IContentService contentService = Services.GetRequiredService<IContentService>();
|
||||
|
||||
var contentItems = new List<IContent>();
|
||||
|
||||
using (ScopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
IContentType contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
contentTypeService.Save(contentType);
|
||||
|
||||
ContentBuilder builder = new ContentBuilder()
|
||||
.WithContentType(contentType);
|
||||
|
||||
Content root = builder.WithName("foo").Build();
|
||||
contentService.SaveAndPublish(root);
|
||||
|
||||
contentItems.Add(builder.WithParent(root).WithName("bar").Build());
|
||||
contentItems.Add(builder.WithParent(root).WithName("baz").Build());
|
||||
|
||||
foreach (IContent content in contentItems)
|
||||
{
|
||||
contentService.SaveAndPublish(content);
|
||||
}
|
||||
}
|
||||
|
||||
var queryParameters = new Dictionary<string, object>
|
||||
{
|
||||
["type"] = Constants.UdiEntityType.Document
|
||||
};
|
||||
|
||||
var url = LinkGenerator.GetUmbracoControllerUrl("GetByIds", typeof(EntityController), queryParameters);
|
||||
|
||||
var udiPayload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
contentItems[0].GetUdi().ToString(),
|
||||
contentItems[1].GetUdi().ToString(),
|
||||
}
|
||||
};
|
||||
|
||||
var intPayload = new
|
||||
{
|
||||
ids = new[]
|
||||
{
|
||||
contentItems[0].Id,
|
||||
contentItems[1].Id,
|
||||
}
|
||||
};
|
||||
|
||||
HttpResponseMessage udiResponse = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, udiPayload);
|
||||
HttpResponseMessage intResponse = await HttpClientJsonExtensions.PostAsJsonAsync(Client, url, intPayload);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(HttpStatusCode.OK, udiResponse.StatusCode, "First request error");
|
||||
Assert.AreEqual(HttpStatusCode.OK, intResponse.StatusCode, "Second request error");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Packaging;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.BackOffice.UrlAndDomains
|
||||
{
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Mapper = true, WithApplication = true,
|
||||
Logger = UmbracoTestOptions.Logger.Console)]
|
||||
public class DomainAndUrlsTests : UmbracoIntegrationTest
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
XDocument xml = PackageMigrationResource.GetEmbeddedPackageDataManifest(GetType());
|
||||
IPackagingService packagingService = GetRequiredService<IPackagingService>();
|
||||
InstallationSummary = packagingService.InstallCompiledPackageData(xml);
|
||||
|
||||
Root = InstallationSummary.ContentInstalled.First();
|
||||
ContentService.SaveAndPublish(Root);
|
||||
|
||||
var cultures = new List<string>();
|
||||
cultures.Add(GetRequiredService<ILocalizationService>().GetDefaultLanguageIsoCode());
|
||||
|
||||
foreach (ILanguage language in InstallationSummary.LanguagesInstalled)
|
||||
{
|
||||
cultures.Add(language.IsoCode);
|
||||
}
|
||||
|
||||
Cultures = cultures.ToArray();
|
||||
|
||||
IHttpContextAccessor httpContextAccessor = GetRequiredService<IHttpContextAccessor>();
|
||||
|
||||
httpContextAccessor.HttpContext = new DefaultHttpContext
|
||||
{
|
||||
Request =
|
||||
{
|
||||
Scheme = "https",
|
||||
Host = new HostString("localhost"),
|
||||
Path = "/",
|
||||
QueryString = new QueryString(string.Empty)
|
||||
}
|
||||
};
|
||||
|
||||
//Like the request middleware we specify the VariationContext to the default language.
|
||||
_variationContextAccessor.VariationContext = new VariationContext(Cultures[0]);
|
||||
GetRequiredService<IUmbracoContextFactory>().EnsureUmbracoContext();
|
||||
}
|
||||
|
||||
private IContentService ContentService => GetRequiredService<IContentService>();
|
||||
|
||||
public InstallationSummary InstallationSummary { get; set; }
|
||||
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder)
|
||||
{
|
||||
builder.Services.AddUnique<IVariationContextAccessor>(_variationContextAccessor);
|
||||
builder.AddNuCache();
|
||||
}
|
||||
|
||||
private readonly TestVariationContextAccessor _variationContextAccessor = new TestVariationContextAccessor();
|
||||
|
||||
public IContent Root { get; set; }
|
||||
public string[] Cultures { get; set; }
|
||||
|
||||
|
||||
[Test]
|
||||
public void Having_three_cultures_and_set_domain_on_all_of_them()
|
||||
{
|
||||
foreach (var culture in Cultures)
|
||||
{
|
||||
SetDomainOnContent(Root, culture, GetDomainUrlFromCultureCode(culture));
|
||||
}
|
||||
|
||||
IEnumerable<UrlInfo> rootUrls = GetContentUrlsAsync(Root);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(6, rootUrls.Count());
|
||||
foreach (var culture in Cultures)
|
||||
{
|
||||
var domain = GetDomainUrlFromCultureCode(culture);
|
||||
Assert.IsTrue(rootUrls.Any(x => x.Text == domain));
|
||||
Assert.IsTrue(rootUrls.Any(x => x.Text == "https://localhost" + domain));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Having_three_cultures_but_set_domain_on_a_non_default_language()
|
||||
{
|
||||
var culture = Cultures[1];
|
||||
var domain = GetDomainUrlFromCultureCode(culture);
|
||||
SetDomainOnContent(Root, culture, domain);
|
||||
|
||||
IEnumerable<UrlInfo> rootUrls = GetContentUrlsAsync(Root);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(4, rootUrls.Count());
|
||||
|
||||
//We expect two for the domain that is setup
|
||||
Assert.IsTrue(rootUrls.Any(x => x.IsUrl && x.Text == domain && x.Culture == culture));
|
||||
Assert.IsTrue(rootUrls.Any(x => x.IsUrl && x.Text == "https://localhost" + domain && x.Culture == culture));
|
||||
|
||||
//We expect the default language to be routable on the default path "/"
|
||||
Assert.IsTrue(rootUrls.Any(x=>x.IsUrl && x.Text == "/" && x.Culture == Cultures[0]));
|
||||
|
||||
//We dont expect non-default languages without a domain to be routable
|
||||
Assert.IsTrue(rootUrls.Any(x=>x.IsUrl == false && x.Culture == Cultures[2]));
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetDomainUrlFromCultureCode(string culture) =>
|
||||
"/" + culture.Replace("-", string.Empty).ToLower() + "/";
|
||||
|
||||
private void SetDomainOnContent(IContent content, string cultureIsoCode, string domain)
|
||||
{
|
||||
IDomainService domainService = GetRequiredService<IDomainService>();
|
||||
var langId = GetRequiredService<ILocalizationService>().GetLanguageIdByIsoCode(cultureIsoCode);
|
||||
domainService.Save(
|
||||
new UmbracoDomain(domain) { RootContentId = content.Id, LanguageId = langId });
|
||||
}
|
||||
|
||||
private IEnumerable<UrlInfo> GetContentUrlsAsync(IContent root) =>
|
||||
root.GetContentUrlsAsync(
|
||||
GetRequiredService<IPublishedRouter>(),
|
||||
GetRequiredService<IUmbracoContextAccessor>().GetRequiredUmbracoContext(),
|
||||
GetRequiredService<ILocalizationService>(),
|
||||
GetRequiredService<ILocalizedTextService>(),
|
||||
ContentService,
|
||||
GetRequiredService<IVariationContextAccessor>(),
|
||||
GetRequiredService<ILogger<IContent>>(),
|
||||
GetRequiredService<UriUtility>(),
|
||||
GetRequiredService<IPublishedUrlProvider>()
|
||||
).GetAwaiter().GetResult();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<umbPackage>
|
||||
<info>
|
||||
<package>
|
||||
<name>Test</name>
|
||||
</package>
|
||||
</info>
|
||||
<Documents>
|
||||
<DocumentSet importMode="root">
|
||||
<textPageLang id="5818" key="092b28ba-f1ce-4469-9573-ed716cfe32bc" parentID="-1" level="1" creatorID="-1" sortOrder="0" createDate="2021-10-13T15:39:32" updateDate="2021-10-13T15:39:32" nodeName="svSE" urlName="svse" path="-1,5818" isDoc="" nodeName-sv-se="svSE" nodeName-da="daDK" nodeName-en-us="enUS" nodeType="4130" nodeTypeAlias="textPageLang" creatorName="Bjarke Berg" writerName="Bjarke Berg" writerID="−1" template="4129" isPublished="true" />
|
||||
</DocumentSet>
|
||||
</Documents>
|
||||
<DocumentTypes>
|
||||
<DocumentType>
|
||||
<Info>
|
||||
<Name>TextPageLang</Name>
|
||||
<Alias>textPageLang</Alias>
|
||||
<Key>d4a44303-bf68-4f34-9f87-6668ff9e9cdc</Key>
|
||||
<Icon>icon-document</Icon>
|
||||
<Thumbnail>folder.png</Thumbnail>
|
||||
<Description />
|
||||
<AllowAtRoot>True</AllowAtRoot>
|
||||
<IsListView>False</IsListView>
|
||||
<IsElement>False</IsElement>
|
||||
<Variations>Culture</Variations>
|
||||
<Compositions />
|
||||
<AllowedTemplates>
|
||||
<Template>TextPageLang</Template>
|
||||
</AllowedTemplates>
|
||||
<DefaultTemplate>TextPageLang</DefaultTemplate>
|
||||
</Info>
|
||||
<Structure>
|
||||
<DocumentType>textPage</DocumentType>
|
||||
<DocumentType>textPageLang</DocumentType>
|
||||
</Structure>
|
||||
<GenericProperties>
|
||||
<GenericProperty>
|
||||
<Name>Grid</Name>
|
||||
<Alias>grid</Alias>
|
||||
<Key>74dcad47-03e6-4190-a7d5-480bd1d96783</Key>
|
||||
<Type>Umbraco.Grid</Type>
|
||||
<Definition>9ccf22c3-34c5-4e58-b365-a2d806c00540</Definition>
|
||||
<Tab Alias="content">Content</Tab>
|
||||
<SortOrder>0</SortOrder>
|
||||
<Mandatory>False</Mandatory>
|
||||
<LabelOnTop>False</LabelOnTop>
|
||||
<Variations>Culture</Variations>
|
||||
</GenericProperty>
|
||||
</GenericProperties>
|
||||
<Tabs>
|
||||
<Tab>
|
||||
<Id>2074</Id>
|
||||
<Key>1cd3a297-a821-49e9-98d8-5c21ddd2aeaf</Key>
|
||||
<Type>Group</Type>
|
||||
<Caption>Content</Caption>
|
||||
<Alias>content</Alias>
|
||||
<SortOrder>0</SortOrder>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</DocumentType>
|
||||
</DocumentTypes>
|
||||
<MediaTypes />
|
||||
<Templates />
|
||||
<Stylesheets />
|
||||
<Scripts />
|
||||
<PartialViews />
|
||||
<Macros />
|
||||
<MacroPartialViews />
|
||||
<DictionaryItems />
|
||||
<Languages>
|
||||
<Language Id="1003" CultureAlias="da" FriendlyName="dansk" />
|
||||
<Language Id="3" CultureAlias="sv-SE" FriendlyName="svensk (Sverige)" />
|
||||
<Language Id="1" CultureAlias="en-US" FriendlyName="English (United States)" />
|
||||
</Languages>
|
||||
<DataTypes />
|
||||
<MediaItems />
|
||||
</umbPackage>
|
||||
@@ -2,26 +2,7 @@
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AutoFixture;
|
||||
using AutoFixture.AutoMoq;
|
||||
using AutoFixture.Kernel;
|
||||
using AutoFixture.NUnit3;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.BackOffice.Controllers;
|
||||
using Umbraco.Cms.Web.BackOffice.Install;
|
||||
using Umbraco.Cms.Web.BackOffice.Routing;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.AutoFixture
|
||||
{
|
||||
@@ -34,64 +15,8 @@ namespace Umbraco.Cms.Tests.UnitTests.AutoFixture
|
||||
/// [Frozen] can be used to ensure the same variable is injected and available as parameter for the test
|
||||
/// </summary>
|
||||
public AutoMoqDataAttribute()
|
||||
: base(() => AutoMockCustomizations.Default)
|
||||
: base(UmbracoAutoMoqFixtureFactory.CreateDefaultFixture)
|
||||
{
|
||||
}
|
||||
|
||||
internal static class AutoMockCustomizations
|
||||
{
|
||||
public static IFixture Default => new Fixture().Customize(new UmbracoCustomization());
|
||||
|
||||
private class UmbracoCustomization : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<BackOfficeIdentityUser>(
|
||||
u => u.FromFactory<string, string, string>(
|
||||
(a, b, c) => BackOfficeIdentityUser.CreateNew(new GlobalSettings(), a, b, c)));
|
||||
fixture
|
||||
.Customize(new ConstructorCustomization(typeof(UsersController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(InstallController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(PreviewController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(MemberController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(BackOfficeController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(BackOfficeUserManager), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(MemberManager), new GreedyConstructorQuery()));
|
||||
|
||||
fixture.Customize(new AutoMoqCustomization());
|
||||
|
||||
// When requesting an IUserStore ensure we actually uses a IUserLockoutStore
|
||||
fixture.Customize<IUserStore<BackOfficeIdentityUser>>(cc => cc.FromFactory(() => Mock.Of<IUserLockoutStore<BackOfficeIdentityUser>>()));
|
||||
|
||||
fixture.Customize<ConfigConnectionString>(
|
||||
u => u.FromFactory<string, string, string>(
|
||||
(a, b, c) => new ConfigConnectionString(a, b, c)));
|
||||
|
||||
fixture.Customize<IUmbracoVersion>(
|
||||
u => u.FromFactory(
|
||||
() => new UmbracoVersion()));
|
||||
|
||||
fixture.Customize<BackOfficeAreaRoutes>(u => u.FromFactory(
|
||||
() => new BackOfficeAreaRoutes(
|
||||
Options.Create(new GlobalSettings()),
|
||||
Mock.Of<IHostingEnvironment>(x => x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
|
||||
Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run),
|
||||
new UmbracoApiControllerTypeCollection(() => Enumerable.Empty<Type>()))));
|
||||
|
||||
fixture.Customize<PreviewRoutes>(u => u.FromFactory(
|
||||
() => new PreviewRoutes(
|
||||
Options.Create(new GlobalSettings()),
|
||||
Mock.Of<IHostingEnvironment>(x => x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
|
||||
Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run))));
|
||||
|
||||
var connectionStrings = new ConnectionStrings();
|
||||
fixture.Customize<ConnectionStrings>(x => x.FromFactory(() => connectionStrings));
|
||||
|
||||
var httpContextAccessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() };
|
||||
fixture.Customize<HttpContext>(x => x.FromFactory(() => httpContextAccessor.HttpContext));
|
||||
fixture.Customize<IHttpContextAccessor>(x => x.FromFactory(() => httpContextAccessor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using AutoFixture;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.AutoFixture.Customizations
|
||||
{
|
||||
internal class OmitRecursionCustomization : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture) =>
|
||||
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AutoFixture;
|
||||
using AutoFixture.Kernel;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Web.BackOffice.Controllers;
|
||||
using Umbraco.Cms.Web.BackOffice.Install;
|
||||
using Umbraco.Cms.Web.BackOffice.Routing;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.AutoFixture.Customizations
|
||||
{
|
||||
internal class UmbracoCustomizations : ICustomization
|
||||
{
|
||||
public void Customize(IFixture fixture)
|
||||
{
|
||||
fixture.Customize<BackOfficeIdentityUser>(
|
||||
u => u.FromFactory<string, string, string>(
|
||||
(a, b, c) => BackOfficeIdentityUser.CreateNew(new GlobalSettings(), a, b, c)));
|
||||
|
||||
fixture
|
||||
.Customize(new ConstructorCustomization(typeof(UsersController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(InstallController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(PreviewController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(MemberController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(BackOfficeController), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(BackOfficeUserManager), new GreedyConstructorQuery()))
|
||||
.Customize(new ConstructorCustomization(typeof(MemberManager), new GreedyConstructorQuery()));
|
||||
|
||||
// When requesting an IUserStore ensure we actually uses a IUserLockoutStore
|
||||
fixture.Customize<IUserStore<BackOfficeIdentityUser>>(cc => cc.FromFactory(Mock.Of<IUserLockoutStore<BackOfficeIdentityUser>>));
|
||||
|
||||
fixture.Customize<ConfigConnectionString>(
|
||||
u => u.FromFactory<string, string, string>(
|
||||
(a, b, c) => new ConfigConnectionString(a, b, c)));
|
||||
|
||||
fixture.Customize<IUmbracoVersion>(
|
||||
u => u.FromFactory(
|
||||
() => new UmbracoVersion()));
|
||||
|
||||
fixture.Customize<HostingSettings>(x =>
|
||||
x.With(settings => settings.ApplicationVirtualPath, string.Empty));
|
||||
|
||||
fixture.Customize<BackOfficeAreaRoutes>(u => u.FromFactory(
|
||||
() => new BackOfficeAreaRoutes(
|
||||
Options.Create(new GlobalSettings()),
|
||||
Mock.Of<IHostingEnvironment>(x => x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
|
||||
Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run),
|
||||
new UmbracoApiControllerTypeCollection(Enumerable.Empty<Type>))));
|
||||
|
||||
fixture.Customize<PreviewRoutes>(u => u.FromFactory(
|
||||
() => new PreviewRoutes(
|
||||
Options.Create(new GlobalSettings()),
|
||||
Mock.Of<IHostingEnvironment>(x => x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
|
||||
Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run))));
|
||||
|
||||
var configConnectionString = new ConfigConnectionString(
|
||||
"ss",
|
||||
"Data Source=(localdb)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Umbraco.mdf;Integrated Security=True");
|
||||
fixture.Customize<ConfigConnectionString>(x => x.FromFactory(() => configConnectionString));
|
||||
|
||||
var httpContextAccessor = new HttpContextAccessor { HttpContext = new DefaultHttpContext() };
|
||||
fixture.Customize<HttpContext>(x => x.FromFactory(() => httpContextAccessor.HttpContext));
|
||||
fixture.Customize<IHttpContextAccessor>(x => x.FromFactory(() => httpContextAccessor));
|
||||
|
||||
fixture.Customize<WebRoutingSettings>(x => x.With(settings => settings.UmbracoApplicationUrl, "http://localhost:5000"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Cms.Tests.UnitTests.AutoFixture
|
||||
/// [Frozen] can be used to ensure the same variable is injected and available as parameter for the test
|
||||
/// </summary>
|
||||
public InlineAutoMoqDataAttribute(params object[] arguments)
|
||||
: base(() => AutoMoqDataAttribute.AutoMockCustomizations.Default, arguments)
|
||||
: base(UmbracoAutoMoqFixtureFactory.CreateDefaultFixture, arguments)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using AutoFixture;
|
||||
using AutoFixture.AutoMoq;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture.Customizations;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.AutoFixture
|
||||
{
|
||||
internal static class UmbracoAutoMoqFixtureFactory
|
||||
{
|
||||
internal static IFixture CreateDefaultFixture() =>
|
||||
new Fixture()
|
||||
.Customize(new AutoMoqCustomization { ConfigureMembers = true })
|
||||
.Customize(new OmitRecursionCustomization())
|
||||
.Customize(new UmbracoCustomizations());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Logging;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.TestHelpers
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public virtual void Setup()
|
||||
{
|
||||
VariationContextAccessor = new TestVariationContextAccessor();
|
||||
PublishedSnapshotAccessor = new TestPublishedSnapshotAccessor();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown() => SnapshotService?.Dispose();
|
||||
|
||||
protected IShortStringHelper ShortStringHelper { get; } = TestHelper.ShortStringHelper;
|
||||
protected virtual IPublishedModelFactory PublishedModelFactory { get; } = new NoopPublishedModelFactory();
|
||||
protected IContentTypeService ContentTypeService { get; private set; }
|
||||
protected IMediaTypeService MediaTypeService { get; private set; }
|
||||
protected IDataTypeService DataTypeService { get; private set; }
|
||||
protected IDomainService DomainService { get; private set; }
|
||||
protected IPublishedValueFallback PublishedValueFallback { get; private set; }
|
||||
protected IPublishedSnapshotService SnapshotService { get; private set; }
|
||||
protected IVariationContextAccessor VariationContextAccessor { get; private set; }
|
||||
protected TestPublishedSnapshotAccessor PublishedSnapshotAccessor { get; private set; }
|
||||
protected TestNuCacheContentService NuCacheContentService { get; private set; }
|
||||
protected PublishedContentTypeFactory PublishedContentTypeFactory { get; private set; }
|
||||
protected GlobalSettings GlobalSettings { get; } = new();
|
||||
|
||||
protected virtual PropertyValueConverterCollection PropertyValueConverterCollection =>
|
||||
new(() => new[] { new TestSimpleTinyMceValueConverter() });
|
||||
|
||||
protected IPublishedContent GetContent(int id)
|
||||
{
|
||||
IPublishedSnapshot snapshot = GetPublishedSnapshot();
|
||||
IPublishedContent doc = snapshot.Content.GetById(id);
|
||||
Assert.IsNotNull(doc);
|
||||
return doc;
|
||||
}
|
||||
|
||||
protected IPublishedContent GetMedia(int id)
|
||||
{
|
||||
IPublishedSnapshot snapshot = GetPublishedSnapshot();
|
||||
IPublishedContent doc = snapshot.Media.GetById(id);
|
||||
Assert.IsNotNull(doc);
|
||||
return doc;
|
||||
}
|
||||
|
||||
protected UrlProvider GetUrlProvider(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
RequestHandlerSettings requestHandlerSettings,
|
||||
WebRoutingSettings webRoutingSettings,
|
||||
out UriUtility uriUtility)
|
||||
{
|
||||
uriUtility = new UriUtility(Mock.Of<IHostingEnvironment>());
|
||||
var urlProvider = new DefaultUrlProvider(
|
||||
Options.Create(requestHandlerSettings),
|
||||
Mock.Of<ILogger<DefaultUrlProvider>>(),
|
||||
new SiteDomainMapper(),
|
||||
umbracoContextAccessor,
|
||||
uriUtility,
|
||||
Mock.Of<ILocalizationService>(x=>x.GetDefaultLanguageIsoCode() == GlobalSettings.DefaultUILanguage)
|
||||
);
|
||||
|
||||
var publishedUrlProvider = new UrlProvider(
|
||||
umbracoContextAccessor,
|
||||
Options.Create(webRoutingSettings),
|
||||
new UrlProviderCollection(() => new[] { urlProvider }),
|
||||
new MediaUrlProviderCollection(() => Enumerable.Empty<IMediaUrlProvider>()),
|
||||
Mock.Of<IVariationContextAccessor>());
|
||||
|
||||
return publishedUrlProvider;
|
||||
}
|
||||
|
||||
protected static PublishedRouter CreatePublishedRouter(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IEnumerable<IContentFinder> contentFinders = null,
|
||||
IPublishedUrlProvider publishedUrlProvider = null) => new(Options.Create(new WebRoutingSettings()),
|
||||
new ContentFinderCollection(() => contentFinders ?? Enumerable.Empty<IContentFinder>()),
|
||||
new TestLastChanceFinder(), new TestVariationContextAccessor(), Mock.Of<IProfilingLogger>(),
|
||||
Mock.Of<ILogger<PublishedRouter>>(), publishedUrlProvider ?? Mock.Of<IPublishedUrlProvider>(),
|
||||
Mock.Of<IRequestAccessor>(), Mock.Of<IPublishedValueFallback>(), Mock.Of<IFileService>(),
|
||||
Mock.Of<IContentTypeService>(), umbracoContextAccessor, Mock.Of<IEventAggregator>());
|
||||
|
||||
protected IUmbracoContextAccessor GetUmbracoContextAccessor(string urlAsString)
|
||||
{
|
||||
IPublishedSnapshot snapshot = GetPublishedSnapshot();
|
||||
|
||||
var uri = new Uri(urlAsString.Contains(Uri.SchemeDelimiter)
|
||||
? urlAsString
|
||||
: $"http://example.com{urlAsString}");
|
||||
|
||||
IUmbracoContext umbracoContext = Mock.Of<IUmbracoContext>(
|
||||
x => x.CleanedUmbracoUrl == uri
|
||||
&& x.Content == snapshot.Content
|
||||
&& x.PublishedSnapshot == snapshot);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
return umbracoContextAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used as a property editor for any test property that has an editor alias called "Umbraco.Void.RTE"
|
||||
/// </summary>
|
||||
private class TestSimpleTinyMceValueConverter : SimpleTinyMceValueConverter
|
||||
{
|
||||
public override bool IsConverter(IPublishedPropertyType propertyType)
|
||||
=> propertyType.EditorAlias == "Umbraco.Void.RTE";
|
||||
}
|
||||
|
||||
protected static DataType[] GetDefaultDataTypes()
|
||||
{
|
||||
var serializer = new ConfigurationEditorJsonSerializer();
|
||||
|
||||
// create data types, property types and content types
|
||||
var dataType =
|
||||
new DataType(new VoidEditor("Editor", Mock.Of<IDataValueEditorFactory>()), serializer) { Id = 3 };
|
||||
|
||||
return new[] { dataType };
|
||||
}
|
||||
|
||||
protected virtual ServiceContext CreateServiceContext(IContentType[] contentTypes, IMediaType[] mediaTypes,
|
||||
IDataType[] dataTypes)
|
||||
{
|
||||
var contentTypeService = new Mock<IContentTypeService>();
|
||||
contentTypeService.Setup(x => x.GetAll()).Returns(contentTypes);
|
||||
contentTypeService.Setup(x => x.GetAll(It.IsAny<int[]>())).Returns(contentTypes);
|
||||
contentTypeService.Setup(x => x.Get(It.IsAny<string>()))
|
||||
.Returns((string alias) => contentTypes.FirstOrDefault(x => x.Alias.InvariantEquals(alias)));
|
||||
|
||||
var mediaTypeService = new Mock<IMediaTypeService>();
|
||||
mediaTypeService.Setup(x => x.GetAll()).Returns(mediaTypes);
|
||||
mediaTypeService.Setup(x => x.GetAll(It.IsAny<int[]>())).Returns(mediaTypes);
|
||||
mediaTypeService.Setup(x => x.Get(It.IsAny<string>()))
|
||||
.Returns((string alias) => mediaTypes.FirstOrDefault(x => x.Alias.InvariantEquals(alias)));
|
||||
|
||||
var contentTypeServiceBaseFactory = new Mock<IContentTypeBaseServiceProvider>();
|
||||
contentTypeServiceBaseFactory.Setup(x => x.For(It.IsAny<IContentBase>()))
|
||||
.Returns(contentTypeService.Object);
|
||||
|
||||
var dataTypeServiceMock = new Mock<IDataTypeService>();
|
||||
dataTypeServiceMock.Setup(x => x.GetAll()).Returns(dataTypes);
|
||||
|
||||
return ServiceContext.CreatePartial(
|
||||
dataTypeService: dataTypeServiceMock.Object,
|
||||
memberTypeService: Mock.Of<IMemberTypeService>(),
|
||||
memberService: Mock.Of<IMemberService>(),
|
||||
contentTypeService: contentTypeService.Object,
|
||||
mediaTypeService: mediaTypeService.Object,
|
||||
localizationService: Mock.Of<ILocalizationService>(),
|
||||
domainService: Mock.Of<IDomainService>(),
|
||||
fileService: Mock.Of<IFileService>()
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a published snapshot and set the accessor to resolve the created one
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected IPublishedSnapshot GetPublishedSnapshot()
|
||||
{
|
||||
IPublishedSnapshot snapshot = SnapshotService.CreatePublishedSnapshot(null);
|
||||
PublishedSnapshotAccessor.SetCurrent(snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the <see cref="IPublishedSnapshotService'" /> with a source of data
|
||||
/// </summary>
|
||||
/// <param name="contentNodeKits"></param>
|
||||
/// <param name="contentTypes"></param>
|
||||
protected void InitializedCache(
|
||||
IEnumerable<ContentNodeKit> contentNodeKits,
|
||||
IContentType[] contentTypes,
|
||||
IDataType[] dataTypes = null,
|
||||
IEnumerable<ContentNodeKit> mediaNodeKits = null,
|
||||
IMediaType[] mediaTypes = null)
|
||||
{
|
||||
// create a data source for NuCache
|
||||
NuCacheContentService = new TestNuCacheContentService(contentNodeKits, mediaNodeKits);
|
||||
|
||||
IRuntimeState runtime = Mock.Of<IRuntimeState>();
|
||||
Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run);
|
||||
|
||||
// create a service context
|
||||
ServiceContext serviceContext = CreateServiceContext(
|
||||
contentTypes ?? Array.Empty<IContentType>(),
|
||||
mediaTypes ?? Array.Empty<IMediaType>(),
|
||||
dataTypes ?? GetDefaultDataTypes());
|
||||
|
||||
DataTypeService = serviceContext.DataTypeService;
|
||||
ContentTypeService = serviceContext.ContentTypeService;
|
||||
MediaTypeService = serviceContext.MediaTypeService;
|
||||
DomainService = serviceContext.DomainService;
|
||||
|
||||
// create a scope provider
|
||||
IScopeProvider scopeProvider = Mock.Of<IScopeProvider>();
|
||||
Mock.Get(scopeProvider)
|
||||
.Setup(x => x.CreateScope(
|
||||
It.IsAny<IsolationLevel>(),
|
||||
It.IsAny<RepositoryCacheMode>(),
|
||||
It.IsAny<IEventDispatcher>(),
|
||||
It.IsAny<IScopedNotificationPublisher>(),
|
||||
It.IsAny<bool?>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>()))
|
||||
.Returns(Mock.Of<IScope>);
|
||||
|
||||
// create a published content type factory
|
||||
PublishedContentTypeFactory = new PublishedContentTypeFactory(
|
||||
PublishedModelFactory,
|
||||
PropertyValueConverterCollection,
|
||||
DataTypeService);
|
||||
|
||||
ITypeFinder typeFinder = TestHelper.GetTypeFinder();
|
||||
|
||||
var nuCacheSettings = new NuCacheSettings();
|
||||
|
||||
// at last, create the complete NuCache snapshot service!
|
||||
var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true };
|
||||
SnapshotService = new PublishedSnapshotService(
|
||||
options,
|
||||
Mock.Of<ISyncBootStateAccessor>(x => x.GetSyncBootState() == SyncBootState.WarmBoot),
|
||||
new SimpleMainDom(),
|
||||
serviceContext,
|
||||
PublishedContentTypeFactory,
|
||||
PublishedSnapshotAccessor,
|
||||
VariationContextAccessor,
|
||||
Mock.Of<IProfilingLogger>(),
|
||||
NullLoggerFactory.Instance,
|
||||
scopeProvider,
|
||||
NuCacheContentService,
|
||||
new TestDefaultCultureAccessor(),
|
||||
Options.Create(GlobalSettings),
|
||||
PublishedModelFactory,
|
||||
TestHelper.GetHostingEnvironment(),
|
||||
Options.Create(nuCacheSettings),
|
||||
//ContentNestedDataSerializerFactory,
|
||||
new ContentDataSerializer(new DictionaryOfPropertyDataSerializer()));
|
||||
|
||||
// invariant is the current default
|
||||
VariationContextAccessor.VariationContext = new VariationContext();
|
||||
|
||||
PublishedValueFallback = new PublishedValueFallback(serviceContext, VariationContextAccessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.Persistence;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.TestHelpers
|
||||
{
|
||||
public class TestNuCacheContentService : INuCacheContentService
|
||||
{
|
||||
private IPublishedModelFactory PublishedModelFactory { get; } = new NoopPublishedModelFactory();
|
||||
|
||||
public TestNuCacheContentService(params ContentNodeKit[] kits)
|
||||
: this((IEnumerable<ContentNodeKit>)kits)
|
||||
{ }
|
||||
|
||||
public TestNuCacheContentService(IEnumerable<ContentNodeKit> contentKits, IEnumerable<ContentNodeKit> mediaKits = null)
|
||||
{
|
||||
ContentKits = contentKits?.ToDictionary(x => x.Node.Id, x => x) ?? new Dictionary<int, ContentNodeKit>();
|
||||
MediaKits = mediaKits?.ToDictionary(x => x.Node.Id, x => x) ?? new Dictionary<int, ContentNodeKit>();
|
||||
}
|
||||
|
||||
public Dictionary<int, ContentNodeKit> ContentKits { get; }
|
||||
public Dictionary<int, ContentNodeKit> MediaKits { get; }
|
||||
|
||||
// note: it is important to clone the returned kits, as the inner
|
||||
// ContentNode is directly reused and modified by the snapshot service
|
||||
public ContentNodeKit GetContentSource(int id)
|
||||
=> ContentKits.TryGetValue(id, out ContentNodeKit kit) ? kit.Clone(PublishedModelFactory) : default;
|
||||
|
||||
public IEnumerable<ContentNodeKit> GetAllContentSources()
|
||||
=> ContentKits.Values
|
||||
.OrderBy(x => x.Node.Level)
|
||||
.ThenBy(x => x.Node.ParentContentId)
|
||||
.ThenBy(x => x.Node.SortOrder)
|
||||
.Select(x => x.Clone(PublishedModelFactory));
|
||||
|
||||
public IEnumerable<ContentNodeKit> GetBranchContentSources(int id)
|
||||
=> ContentKits.Values
|
||||
.Where(x => x.Node.Path.EndsWith("," + id) || x.Node.Path.Contains("," + id + ","))
|
||||
.OrderBy(x => x.Node.Level)
|
||||
.ThenBy(x => x.Node.ParentContentId)
|
||||
.ThenBy(x => x.Node.SortOrder)
|
||||
.Select(x => x.Clone(PublishedModelFactory));
|
||||
|
||||
public IEnumerable<ContentNodeKit> GetTypeContentSources(IEnumerable<int> ids)
|
||||
=> ContentKits.Values
|
||||
.Where(x => ids.Contains(x.ContentTypeId))
|
||||
.OrderBy(x => x.Node.Level)
|
||||
.ThenBy(x => x.Node.ParentContentId)
|
||||
.ThenBy(x => x.Node.SortOrder)
|
||||
.Select(x => x.Clone(PublishedModelFactory));
|
||||
|
||||
public ContentNodeKit GetMediaSource(int id)
|
||||
=> MediaKits.TryGetValue(id, out ContentNodeKit kit) ? kit.Clone(PublishedModelFactory) : default;
|
||||
|
||||
public IEnumerable<ContentNodeKit> GetAllMediaSources()
|
||||
=> MediaKits.Values
|
||||
.OrderBy(x => x.Node.Level)
|
||||
.ThenBy(x => x.Node.ParentContentId)
|
||||
.ThenBy(x => x.Node.SortOrder)
|
||||
.Select(x => x.Clone(PublishedModelFactory));
|
||||
|
||||
public IEnumerable<ContentNodeKit> GetBranchMediaSources(int id)
|
||||
=> MediaKits.Values
|
||||
.Where(x => x.Node.Path.EndsWith("," + id) || x.Node.Path.Contains("," + id + ","))
|
||||
.OrderBy(x => x.Node.Level)
|
||||
.ThenBy(x => x.Node.ParentContentId)
|
||||
.ThenBy(x => x.Node.SortOrder)
|
||||
.Select(x => x.Clone(PublishedModelFactory));
|
||||
|
||||
public IEnumerable<ContentNodeKit> GetTypeMediaSources(IEnumerable<int> ids)
|
||||
=> MediaKits.Values
|
||||
.Where(x => ids.Contains(x.ContentTypeId))
|
||||
.OrderBy(x => x.Node.Level)
|
||||
.ThenBy(x => x.Node.ParentContentId)
|
||||
.ThenBy(x => x.Node.SortOrder)
|
||||
.Select(x => x.Clone(PublishedModelFactory));
|
||||
|
||||
public void DeleteContentItem(IContentBase item) => throw new NotImplementedException();
|
||||
public void DeleteContentItems(IEnumerable<IContentBase> items) => throw new NotImplementedException();
|
||||
public void RefreshContent(IContent content) => throw new NotImplementedException();
|
||||
|
||||
public void RebuildDatabaseCacheIfSerializerChanged() => throw new NotImplementedException();
|
||||
public void RefreshMedia(IMedia media) => throw new NotImplementedException();
|
||||
public void RefreshMember(IMember member) => throw new NotImplementedException();
|
||||
public void Rebuild(IReadOnlyCollection<int> contentTypeIds = null, IReadOnlyCollection<int> mediaTypeIds = null, IReadOnlyCollection<int> memberTypeIds = null) => throw new NotImplementedException();
|
||||
|
||||
public bool VerifyContentDbCache() => throw new NotImplementedException();
|
||||
public bool VerifyMediaDbCache() => throw new NotImplementedException();
|
||||
public bool VerifyMemberDbCache() => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Collections;
|
||||
|
||||
namespace Umbraco.Tests.Collections
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Collections
|
||||
{
|
||||
[TestFixture]
|
||||
public class StackQueueTests
|
||||
@@ -10,13 +10,13 @@ namespace Umbraco.Tests.Collections
|
||||
public void Queue()
|
||||
{
|
||||
var sq = new StackQueue<int>();
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
sq.Enqueue(i);
|
||||
}
|
||||
|
||||
var expected = 0;
|
||||
while(sq.Count > 0)
|
||||
while (sq.Count > 0)
|
||||
{
|
||||
var next = sq.Dequeue();
|
||||
Assert.AreEqual(expected, next);
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.Collections
|
||||
public void Stack()
|
||||
{
|
||||
var sq = new StackQueue<int>();
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
sq.Push(i);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Tests.Collections
|
||||
public void Stack_And_Queue()
|
||||
{
|
||||
var sq = new StackQueue<int>();
|
||||
for (int i = 0; i < 5; i++)
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Configurations
|
||||
{
|
||||
[TestFixture]
|
||||
public class LanguageXmlTests
|
||||
{
|
||||
[Test]
|
||||
[Platform("Win")] //TODO figure out why Path.GetFullPath("/mnt/c/...") is not considered an absolute path on linux + mac
|
||||
public void Can_Load_Language_Xml_Files()
|
||||
{
|
||||
var languageDirectoryPath = GetLanguageDirectory();
|
||||
var readFilesCount = 0;
|
||||
var xmlDocument = new XmlDocument();
|
||||
|
||||
var directoryInfo = new DirectoryInfo(languageDirectoryPath);
|
||||
|
||||
foreach (var languageFile in directoryInfo.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
// Load will throw an exception if the XML isn't valid.
|
||||
xmlDocument.Load(languageFile.FullName);
|
||||
readFilesCount++;
|
||||
}
|
||||
|
||||
// Ensure that at least one file was read.
|
||||
Assert.AreNotEqual(0, readFilesCount);
|
||||
}
|
||||
|
||||
private static string GetLanguageDirectory()
|
||||
{
|
||||
var testDirectoryPathParts = Path.GetDirectoryName(TestContext.CurrentContext.TestDirectory)
|
||||
.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
var solutionDirectoryPathParts = testDirectoryPathParts
|
||||
.Take(Array.IndexOf(testDirectoryPathParts, "tests"));
|
||||
var languageFolderPathParts = new List<string>(solutionDirectoryPathParts);
|
||||
var additionalPathParts = new[] { "Umbraco.Web.UI", "umbraco", "config", "lang" };
|
||||
languageFolderPathParts.AddRange(additionalPathParts);
|
||||
|
||||
// Hack for build-server - when this path is generated in that envrionment it's missing the "src" folder.
|
||||
// Not sure why, but if it's missing we'll add it in the right place.
|
||||
if (!languageFolderPathParts.Contains("src"))
|
||||
{
|
||||
languageFolderPathParts.Insert(languageFolderPathParts.Count - additionalPathParts.Length, "src");
|
||||
}
|
||||
|
||||
return string.Join(Path.DirectorySeparatorChar.ToString(), languageFolderPathParts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Logging;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
// TODO: We should be able to decouple this from the base db tests since we're just mocking the services now
|
||||
|
||||
[TestFixture]
|
||||
public class ContentFinderByAliasTests : UrlRoutingTestBase
|
||||
{
|
||||
|
||||
[TestCase("/this/is/my/alias", 1001)]
|
||||
[TestCase("/anotheralias", 1001)]
|
||||
[TestCase("/page2/alias", 10011)]
|
||||
[TestCase("/2ndpagealias", 10011)]
|
||||
[TestCase("/only/one/alias", 100111)]
|
||||
[TestCase("/ONLY/one/Alias", 100111)]
|
||||
[TestCase("/alias43", 100121)]
|
||||
public async Task Lookup_By_Url_Alias(string urlAsString, int nodeMatch)
|
||||
{
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(urlAsString);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var lookup =
|
||||
new ContentFinderByUrlAlias(Mock.Of<ILogger<ContentFinderByUrlAlias>>(), Mock.Of<IPublishedValueFallback>(), VariationContextAccessor, umbracoContextAccessor);
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -8,40 +9,18 @@ using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentFinderByAliasWithDomainsTests : ContentFinderByAliasTests
|
||||
public class ContentFinderByAliasWithDomainsTests : UrlRoutingTestBase
|
||||
{
|
||||
private PublishedContentType _publishedContentType;
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
var properties = new[]
|
||||
{
|
||||
new PublishedPropertyType(
|
||||
propertyTypeAlias:"umbracoUrlAlias",
|
||||
dataTypeId: Constants.DataTypes.Textbox,
|
||||
isUserProperty:false,
|
||||
variations: ContentVariation.Nothing,
|
||||
propertyValueConverters:new PropertyValueConverterCollection(Enumerable.Empty<IPropertyValueConverter>()),
|
||||
contentType:Mock.Of<IPublishedContentType>(),
|
||||
publishedModelFactory:Mock.Of<IPublishedModelFactory>(),
|
||||
factory:Mock.Of<IPublishedContentTypeFactory>()
|
||||
)
|
||||
};
|
||||
_publishedContentType = new PublishedContentType(Guid.NewGuid(), 0, "Doc", PublishedItemType.Content, Enumerable.Empty<string>(), properties, ContentVariation.Nothing);
|
||||
}
|
||||
|
||||
protected override PublishedContentType GetPublishedContentTypeByAlias(string alias)
|
||||
{
|
||||
if (alias == "Doc") return _publishedContentType;
|
||||
return null;
|
||||
}
|
||||
|
||||
[TestCase("http://domain1.com/this/is/my/alias", "de-DE", -1001)] // alias to domain's page fails - no alias on domain's home
|
||||
[TestCase("http://domain1.com/page2/alias", "de-DE", 10011)] // alias to sub-page works
|
||||
@@ -56,10 +35,11 @@ namespace Umbraco.Tests.Routing
|
||||
public async Task Lookup_By_Url_Alias_And_Domain(string inputUrl, string expectedCulture, int expectedNode)
|
||||
{
|
||||
//SetDomains1();
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(inputUrl);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
|
||||
var umbracoContext = GetUmbracoContext(inputUrl);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext));
|
||||
var request = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var request = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
// must lookup domain
|
||||
publishedRouter.FindDomain(request);
|
||||
|
||||
@@ -68,7 +48,7 @@ namespace Umbraco.Tests.Routing
|
||||
Assert.AreEqual(expectedCulture, request.Culture);
|
||||
}
|
||||
|
||||
var finder = new ContentFinderByUrlAlias(LoggerFactory.CreateLogger<ContentFinderByUrlAlias>(), Mock.Of<IPublishedValueFallback>(), VariationContextAccessor, GetUmbracoContextAccessor(umbracoContext));
|
||||
var finder = new ContentFinderByUrlAlias(Mock.Of<ILogger<ContentFinderByUrlAlias>>(), Mock.Of<IPublishedValueFallback>(), VariationContextAccessor, umbracoContextAccessor);
|
||||
var result = finder.TryFindContent(request);
|
||||
|
||||
if (expectedNode > 0)
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentFinderByIdTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
}
|
||||
|
||||
[TestCase("/1046", 1046)]
|
||||
public async Task Lookup_By_Id(string urlAsString, int nodeMatch)
|
||||
{
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(urlAsString);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var webRoutingSettings = new WebRoutingSettings();
|
||||
var lookup = new ContentFinderByIdPath(Options.Create(webRoutingSettings), Mock.Of<ILogger<ContentFinderByIdPath>>(), Mock.Of<IRequestAccessor>(), umbracoContextAccessor);
|
||||
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentFinderByPageIdQueryTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
}
|
||||
|
||||
[TestCase("/?umbPageId=1046", 1046)]
|
||||
[TestCase("/?UMBPAGEID=1046", 1046)]
|
||||
[TestCase("/default.aspx?umbPageId=1046", 1046)] // TODO: Should this match??
|
||||
[TestCase("/some/other/page?umbPageId=1046", 1046)] // TODO: Should this match??
|
||||
[TestCase("/some/other/page.aspx?umbPageId=1046", 1046)] // TODO: Should this match??
|
||||
public async Task Lookup_By_Page_Id(string urlAsString, int nodeMatch)
|
||||
{
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(urlAsString);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
var queryStrings = HttpUtility.ParseQueryString(umbracoContext.CleanedUmbracoUrl.Query);
|
||||
|
||||
var mockRequestAccessor = new Mock<IRequestAccessor>();
|
||||
mockRequestAccessor.Setup(x => x.GetRequestValue("umbPageID"))
|
||||
.Returns(queryStrings["umbPageID"]);
|
||||
|
||||
var lookup = new ContentFinderByPageIdQuery(mockRequestAccessor.Object, umbracoContextAccessor);
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentFinderByUrlAndTemplateTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private IFileService _fileService;
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
}
|
||||
|
||||
protected override ServiceContext CreateServiceContext(IContentType[] contentTypes, IMediaType[] mediaTypes, IDataType[] dataTypes)
|
||||
{
|
||||
var serviceContext = base.CreateServiceContext(contentTypes, mediaTypes, dataTypes);
|
||||
|
||||
var fileService = Mock.Get(serviceContext.FileService);
|
||||
fileService.Setup(x => x.GetTemplate(It.IsAny<string>()))
|
||||
.Returns((string alias) => new Template(ShortStringHelper, alias, alias));
|
||||
|
||||
_fileService = fileService.Object;
|
||||
|
||||
return serviceContext;
|
||||
}
|
||||
|
||||
[TestCase("/blah")]
|
||||
[TestCase("/home/Sub1/blah")]
|
||||
[TestCase("/Home/Sub1/Blah")] //different cases
|
||||
public async Task Match_Document_By_Url_With_Template(string urlAsString)
|
||||
{
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(urlAsString);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
var webRoutingSettings = new WebRoutingSettings();
|
||||
var lookup = new ContentFinderByUrlAndTemplate(
|
||||
Mock.Of<ILogger<ContentFinderByUrlAndTemplate>>(),
|
||||
_fileService,
|
||||
ContentTypeService,
|
||||
umbracoContextAccessor,
|
||||
Microsoft.Extensions.Options.Options.Create(webRoutingSettings));
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
IPublishedRequest request = frequest.Build();
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.IsNotNull(frequest.PublishedContent);
|
||||
var templateAlias = request.GetTemplateAlias();
|
||||
Assert.IsNotNull(templateAlias);
|
||||
Assert.AreEqual("blah".ToUpperInvariant(), templateAlias.ToUpperInvariant());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentFinderByUrlTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private async Task<(ContentFinderByUrl finder, IPublishedRequestBuilder frequest)> GetContentFinder(string urlString)
|
||||
{
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(urlString);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var lookup = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
return (lookup, frequest);
|
||||
}
|
||||
|
||||
[TestCase("/", 1046)]
|
||||
[TestCase("/Sub1", 1173)]
|
||||
[TestCase("/sub1", 1173)]
|
||||
[TestCase("/home/sub1", -1)] // should fail
|
||||
|
||||
// these two are special. getNiceUrl(1046) returns "/" but getNiceUrl(1172) cannot also return "/" so
|
||||
// we've made it return "/test-page" => we have to support that URL back in the lookup...
|
||||
[TestCase("/home", 1046)]
|
||||
[TestCase("/test-page", 1172)]
|
||||
public async Task Match_Document_By_Url_Hide_Top_Level(string urlString, int expectedId)
|
||||
{
|
||||
GlobalSettings.HideTopLevelNodeFromPath = true;
|
||||
|
||||
var lookup = await GetContentFinder(urlString);
|
||||
|
||||
Assert.IsTrue(GlobalSettings.HideTopLevelNodeFromPath);
|
||||
|
||||
// FIXME: debugging - going further down, the routes cache is NOT empty?!
|
||||
if (urlString == "/home/sub1")
|
||||
System.Diagnostics.Debugger.Break();
|
||||
|
||||
var result = lookup.finder.TryFindContent(lookup.frequest);
|
||||
|
||||
if (expectedId > 0)
|
||||
{
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, lookup.frequest.PublishedContent.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(result);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("/", 1046)]
|
||||
[TestCase("/home", 1046)]
|
||||
[TestCase("/home/Sub1", 1173)]
|
||||
[TestCase("/Home/Sub1", 1173)] //different cases
|
||||
public async Task Match_Document_By_Url(string urlString, int expectedId)
|
||||
{
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var lookup = await GetContentFinder(urlString);
|
||||
|
||||
Assert.IsFalse(GlobalSettings.HideTopLevelNodeFromPath);
|
||||
|
||||
var result = lookup.finder.TryFindContent(lookup.frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, lookup.frequest.PublishedContent.Id);
|
||||
}
|
||||
/// <summary>
|
||||
/// This test handles requests with special characters in the URL.
|
||||
/// </summary>
|
||||
/// <param name="urlString"></param>
|
||||
/// <param name="expectedId"></param>
|
||||
[TestCase("/", 1046)]
|
||||
[TestCase("/home/sub1/custom-sub-3-with-accént-character", 1179)]
|
||||
[TestCase("/home/sub1/custom-sub-4-with-æøå", 1180)]
|
||||
public async Task Match_Document_By_Url_With_Special_Characters(string urlString, int expectedId)
|
||||
{
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var lookup = await GetContentFinder(urlString);
|
||||
|
||||
var result = lookup.finder.TryFindContent(lookup.frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, lookup.frequest.PublishedContent.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This test handles requests with a hostname associated.
|
||||
/// The logic for handling this goes through the DomainHelper and is a bit different
|
||||
/// from what happens in a normal request - so it has a separate test with a mocked
|
||||
/// hostname added.
|
||||
/// </summary>
|
||||
/// <param name="urlString"></param>
|
||||
/// <param name="expectedId"></param>
|
||||
[TestCase("/", 1046)]
|
||||
[TestCase("/home/sub1/custom-sub-3-with-accént-character", 1179)]
|
||||
[TestCase("/home/sub1/custom-sub-4-with-æøå", 1180)]
|
||||
public async Task Match_Document_By_Url_With_Special_Characters_Using_Hostname(string urlString, int expectedId)
|
||||
{
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var lookup = await GetContentFinder(urlString);
|
||||
|
||||
lookup.frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite", -1, "en-US", false), new Uri("http://mysite/")));
|
||||
|
||||
var result = lookup.finder.TryFindContent(lookup.frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, lookup.frequest.PublishedContent.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This test handles requests with a hostname with special characters associated.
|
||||
/// The logic for handling this goes through the DomainHelper and is a bit different
|
||||
/// from what happens in a normal request - so it has a separate test with a mocked
|
||||
/// hostname added.
|
||||
/// </summary>
|
||||
/// <param name="urlString"></param>
|
||||
/// <param name="expectedId"></param>
|
||||
[TestCase("/æøå/", 1046)]
|
||||
[TestCase("/æøå/home/sub1", 1173)]
|
||||
[TestCase("/æøå/home/sub1/custom-sub-3-with-accént-character", 1179)]
|
||||
[TestCase("/æøå/home/sub1/custom-sub-4-with-æøå", 1180)]
|
||||
public async Task Match_Document_By_Url_With_Special_Characters_In_Hostname(string urlString, int expectedId)
|
||||
{
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var lookup = await GetContentFinder(urlString);
|
||||
|
||||
lookup.frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite/æøå", -1, "en-US", false), new Uri("http://mysite/æøå")));
|
||||
|
||||
var result = lookup.finder.TryFindContent(lookup.frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, lookup.frequest.PublishedContent.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,47 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class ContentFinderByUrlWithDomainsTests : UrlRoutingTestBase
|
||||
{
|
||||
void SetDomains3()
|
||||
private void SetDomains3()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/") {Id = 1, LanguageId = LangDeId, RootContentId = 1001, LanguageIsoCode = "de-DE"}
|
||||
});
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/") {Id = 1, LanguageId = LangDeId, RootContentId = 1001, LanguageIsoCode = "de-DE"}
|
||||
});
|
||||
}
|
||||
|
||||
void SetDomains4()
|
||||
private void SetDomains4()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("domain1.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain3.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1003, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10031, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10032, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("domain1.com/en") {Id = 2, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("domain1.com/fr") {Id = 3, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain3.com/") {Id = 4, LanguageId = LangEngId, RootContentId = 1003, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/en") {Id = 5, LanguageId = LangEngId, RootContentId = 10031, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/fr") {Id = 6, LanguageId = LangFrId, RootContentId = 10032, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Doc ANY>
|
||||
<!ATTLIST Doc id ID #REQUIRED>
|
||||
@@ -115,7 +120,6 @@ namespace Umbraco.Tests.Routing
|
||||
</Doc>
|
||||
</Doc>
|
||||
</root>";
|
||||
}
|
||||
|
||||
[TestCase("http://domain1.com/", 1001)]
|
||||
[TestCase("http://domain1.com/1001-1", 10011)]
|
||||
@@ -125,16 +129,17 @@ namespace Umbraco.Tests.Routing
|
||||
{
|
||||
SetDomains3();
|
||||
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = true;
|
||||
|
||||
var umbracoContext = GetUmbracoContext(url, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory);
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(url);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// must lookup domain else lookup by URL fails
|
||||
publishedRouter.FindDomain(frequest);
|
||||
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var lookup = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, frequest.PublishedContent.Id);
|
||||
@@ -164,19 +169,20 @@ namespace Umbraco.Tests.Routing
|
||||
SetDomains4();
|
||||
|
||||
// defaults depend on test environment
|
||||
expectedCulture = expectedCulture ?? System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
|
||||
expectedCulture ??= System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
|
||||
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = true;
|
||||
|
||||
var umbracoContext = GetUmbracoContext(url, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory);
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(url);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// must lookup domain else lookup by URL fails
|
||||
publishedRouter.FindDomain(frequest);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var lookup = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(expectedId, frequest.PublishedContent.Id);
|
||||
@@ -1,124 +1,151 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
internal class DomainsAndCulturesTests : UrlRoutingTestBase
|
||||
public class DomainsAndCulturesTests : UrlRoutingTestBase
|
||||
{
|
||||
protected override void Compose()
|
||||
{
|
||||
base.Compose();
|
||||
|
||||
Builder.Services.AddTransient<ISiteDomainMapper, SiteDomainMapper>();
|
||||
}
|
||||
|
||||
private void SetDomains1()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/")
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangDeId,
|
||||
RootContentId = 1001,
|
||||
LanguageIsoCode = "de-DE"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/en")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangEngId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "en-US"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/fr")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangFrId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "fr-FR"
|
||||
}
|
||||
});
|
||||
new UmbracoDomain("domain1.com/")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangDeId,
|
||||
RootContentId = 1001,
|
||||
LanguageIsoCode = "de-DE"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/en")
|
||||
{
|
||||
Id = 2,
|
||||
LanguageId = LangEngId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "en-US"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/fr")
|
||||
{
|
||||
Id = 3,
|
||||
LanguageId = LangFrId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "fr-FR"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void SetDomains2()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/")
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangDeId,
|
||||
RootContentId = 1001,
|
||||
LanguageIsoCode = "de-DE"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/en")
|
||||
new UmbracoDomain("domain1.com/")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangDeId,
|
||||
RootContentId = 1001,
|
||||
LanguageIsoCode = "de-DE"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/en")
|
||||
{
|
||||
Id = 2,
|
||||
LanguageId = LangEngId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "en-US"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/fr")
|
||||
{
|
||||
Id = 3,
|
||||
LanguageId = LangFrId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "fr-FR"
|
||||
},
|
||||
new UmbracoDomain("*1001")
|
||||
{
|
||||
Id = 4,
|
||||
LanguageId = LangDeId,
|
||||
RootContentId = 1001,
|
||||
LanguageIsoCode = "de-DE"
|
||||
},
|
||||
new UmbracoDomain("*10011")
|
||||
{
|
||||
Id = 5,
|
||||
LanguageId = LangCzId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "cs-CZ"
|
||||
},
|
||||
new UmbracoDomain("*100112")
|
||||
{
|
||||
Id = 6,
|
||||
LanguageId = LangNlId,
|
||||
RootContentId = 100112,
|
||||
LanguageIsoCode = "nl-NL"
|
||||
},
|
||||
new UmbracoDomain("*1001122")
|
||||
{
|
||||
Id = 7,
|
||||
LanguageId = LangDkId,
|
||||
RootContentId = 1001122,
|
||||
LanguageIsoCode = "da-DK"
|
||||
},
|
||||
new UmbracoDomain("*10012")
|
||||
{
|
||||
Id = 8,
|
||||
LanguageId = LangNlId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "nl-NL"
|
||||
},
|
||||
new UmbracoDomain("*10031")
|
||||
{
|
||||
Id = 9,
|
||||
LanguageId = LangNlId,
|
||||
RootContentId =10031,
|
||||
LanguageIsoCode = "nl-NL"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// domains such as "/en" are natively supported, and when instanciating
|
||||
// DomainAndUri for them, the host will come from the current request
|
||||
//
|
||||
private void SetDomains3()
|
||||
{
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangEngId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "en-US"
|
||||
},
|
||||
new UmbracoDomain("domain1.com/fr")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangFrId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "fr-FR"
|
||||
},
|
||||
new UmbracoDomain("*1001")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangDeId,
|
||||
RootContentId = 1001,
|
||||
LanguageIsoCode = "de-DE"
|
||||
},
|
||||
new UmbracoDomain("*10011")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangCzId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "cs-CZ"
|
||||
},
|
||||
new UmbracoDomain("*100112")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangNlId,
|
||||
RootContentId = 100112,
|
||||
LanguageIsoCode = "nl-NL"
|
||||
},
|
||||
new UmbracoDomain("*1001122")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangDkId,
|
||||
RootContentId = 1001122,
|
||||
LanguageIsoCode = "da-DK"
|
||||
},
|
||||
new UmbracoDomain("*10012")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangNlId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "nl-NL"
|
||||
},
|
||||
new UmbracoDomain("*10031")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangNlId,
|
||||
RootContentId =10031,
|
||||
LanguageIsoCode = "nl-NL"
|
||||
}
|
||||
});
|
||||
new UmbracoDomain("/en")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangEngId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "en-US"
|
||||
},
|
||||
new UmbracoDomain("/fr")
|
||||
{
|
||||
Id = 2,
|
||||
LanguageId = LangFrId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "fr-FR"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Doc ANY>
|
||||
<!ATTLIST Doc id ID #REQUIRED>
|
||||
@@ -250,7 +277,6 @@ namespace Umbraco.Tests.Routing
|
||||
</Doc>
|
||||
</Doc>
|
||||
</root>";
|
||||
}
|
||||
|
||||
#region Cases
|
||||
[TestCase("http://domain1.com/", "de-DE", 1001)]
|
||||
@@ -265,18 +291,19 @@ namespace Umbraco.Tests.Routing
|
||||
{
|
||||
SetDomains1();
|
||||
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory);
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(inputUrl);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var finder = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var finder = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = finder.TryFindContent(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
@@ -311,19 +338,20 @@ namespace Umbraco.Tests.Routing
|
||||
SetDomains2();
|
||||
|
||||
// defaults depend on test environment
|
||||
expectedCulture = expectedCulture ?? System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
|
||||
expectedCulture ??= System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
|
||||
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory);
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(inputUrl);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
|
||||
// find document
|
||||
var finder = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var finder = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = finder.TryFindContent(frequest);
|
||||
|
||||
// apply wildcard domain
|
||||
@@ -333,29 +361,7 @@ namespace Umbraco.Tests.Routing
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
Assert.AreEqual(frequest.PublishedContent.Id, expectedNode);
|
||||
}
|
||||
// domains such as "/en" are natively supported, and when instanciating
|
||||
// DomainAndUri for them, the host will come from the current request
|
||||
//
|
||||
private void SetDomains3()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("/en")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangEngId,
|
||||
RootContentId = 10011,
|
||||
LanguageIsoCode = "en-US"
|
||||
},
|
||||
new UmbracoDomain("/fr")
|
||||
{
|
||||
Id = 1,
|
||||
LanguageId = LangFrId,
|
||||
RootContentId = 10012,
|
||||
LanguageIsoCode = "fr-FR"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#region Cases
|
||||
[TestCase("http://domain1.com/en", "en-US", 10011)]
|
||||
@@ -367,10 +373,13 @@ namespace Umbraco.Tests.Routing
|
||||
{
|
||||
SetDomains3();
|
||||
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory);
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(inputUrl);
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
@@ -378,7 +387,7 @@ namespace Umbraco.Tests.Routing
|
||||
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var finder = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var finder = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = finder.TryFindContent(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
@@ -0,0 +1,216 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class GetContentUrlsTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private WebRoutingSettings _webRoutingSettings;
|
||||
private RequestHandlerSettings _requestHandlerSettings;
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
_webRoutingSettings = new WebRoutingSettings();
|
||||
_requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
}
|
||||
|
||||
private ILocalizedTextService GetTextService()
|
||||
{
|
||||
var textService = new Mock<ILocalizedTextService>();
|
||||
textService.Setup(x => x.Localize(
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<CultureInfo>(),
|
||||
It.IsAny<IDictionary<string, string>>()
|
||||
))
|
||||
.Returns((string key, string alias, CultureInfo culture, IDictionary<string, string> args)
|
||||
=> $"{key}/{alias}");
|
||||
|
||||
return textService.Object;
|
||||
}
|
||||
|
||||
private ILocalizationService GetLangService(params string[] isoCodes)
|
||||
{
|
||||
var allLangs = isoCodes
|
||||
.Select(CultureInfo.GetCultureInfo)
|
||||
.Select(culture => new Language(GlobalSettings, culture.Name)
|
||||
{
|
||||
CultureName = culture.DisplayName,
|
||||
IsDefault = true,
|
||||
IsMandatory = true
|
||||
}).ToArray();
|
||||
|
||||
|
||||
var langServiceMock = new Mock<ILocalizationService>();
|
||||
langServiceMock.Setup(x => x.GetAllLanguages()).Returns(allLangs);
|
||||
langServiceMock.Setup(x => x.GetDefaultLanguageIsoCode()).Returns(allLangs.First(x=>x.IsDefault).IsoCode);
|
||||
|
||||
return langServiceMock.Object;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Content_Not_Published()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
var content = ContentBuilder.CreateBasicContent(contentType);
|
||||
content.Id = 1046; // FIXME: we are using this ID only because it's built into the test XML published cache
|
||||
content.Path = "-1,1046";
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://localhost:8000");
|
||||
var publishedRouter = CreatePublishedRouter(
|
||||
umbracoContextAccessor,
|
||||
new[] { new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor) });
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, _requestHandlerSettings, _webRoutingSettings, out UriUtility uriUtility);
|
||||
|
||||
var urls = (await content.GetContentUrlsAsync(
|
||||
publishedRouter,
|
||||
umbracoContext,
|
||||
GetLangService("en-US", "fr-FR"),
|
||||
GetTextService(),
|
||||
Mock.Of<IContentService>(),
|
||||
VariationContextAccessor,
|
||||
Mock.Of<ILogger<IContent>>(),
|
||||
uriUtility,
|
||||
urlProvider)).ToList();
|
||||
|
||||
Assert.AreEqual(1, urls.Count);
|
||||
Assert.AreEqual("content/itemNotPublished", urls[0].Text);
|
||||
Assert.IsFalse(urls[0].IsUrl);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Invariant_Root_Content_Published_No_Domains()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
var content = ContentBuilder.CreateBasicContent(contentType);
|
||||
content.Id = 1046; // FIXME: we are using this ID only because it's built into the test XML published cache
|
||||
content.Path = "-1,1046";
|
||||
content.Published = true;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://localhost:8000");
|
||||
var publishedRouter = CreatePublishedRouter(
|
||||
umbracoContextAccessor,
|
||||
new[] { new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor) });
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, _requestHandlerSettings, _webRoutingSettings, out UriUtility uriUtility);
|
||||
|
||||
var urls = (await content.GetContentUrlsAsync(
|
||||
publishedRouter,
|
||||
umbracoContext,
|
||||
GetLangService("en-US", "fr-FR"),
|
||||
GetTextService(),
|
||||
Mock.Of<IContentService>(),
|
||||
VariationContextAccessor,
|
||||
Mock.Of<ILogger<IContent>>(),
|
||||
uriUtility,
|
||||
urlProvider)).ToList();
|
||||
|
||||
|
||||
Assert.AreEqual(2, urls.Count);
|
||||
|
||||
var enUrl = urls.First(x => x.Culture == "en-US");
|
||||
|
||||
Assert.AreEqual("/home/", enUrl.Text);
|
||||
Assert.AreEqual("en-US", enUrl.Culture);
|
||||
Assert.IsTrue(enUrl.IsUrl);
|
||||
|
||||
var frUrl = urls.First(x => x.Culture == "fr-FR");
|
||||
|
||||
Assert.IsFalse(frUrl.IsUrl);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Invariant_Child_Content_Published_No_Domains()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
var parent = ContentBuilder.CreateBasicContent(contentType);
|
||||
parent.Id = 1046; // FIXME: we are using this ID only because it's built into the test XML published cache
|
||||
parent.Name = "home";
|
||||
parent.Path = "-1,1046";
|
||||
parent.Published = true;
|
||||
var child = ContentBuilder.CreateBasicContent(contentType);
|
||||
child.Name = "sub1";
|
||||
child.Id = 1173; // FIXME: we are using this ID only because it's built into the test XML published cache
|
||||
child.Path = "-1,1046,1173";
|
||||
child.Published = true;
|
||||
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://localhost:8000");
|
||||
var publishedRouter = CreatePublishedRouter(
|
||||
umbracoContextAccessor,
|
||||
new[] { new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor) });
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
|
||||
|
||||
var localizationService = GetLangService("en-US", "fr-FR");
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, _requestHandlerSettings, _webRoutingSettings, out UriUtility uriUtility);
|
||||
|
||||
var urls = (await child.GetContentUrlsAsync(
|
||||
publishedRouter,
|
||||
umbracoContext,
|
||||
localizationService,
|
||||
GetTextService(),
|
||||
Mock.Of<IContentService>(),
|
||||
VariationContextAccessor,
|
||||
Mock.Of<ILogger<IContent>>(),
|
||||
uriUtility,
|
||||
urlProvider)).ToList();
|
||||
|
||||
Assert.AreEqual(2, urls.Count);
|
||||
|
||||
var enUrl = urls.First(x => x.Culture == "en-US");
|
||||
|
||||
Assert.AreEqual("/home/sub1/", enUrl.Text);
|
||||
Assert.AreEqual("en-US", enUrl.Culture);
|
||||
Assert.IsTrue(enUrl.IsUrl);
|
||||
|
||||
var frUrl = urls.First(x => x.Culture == "fr-FR");
|
||||
|
||||
Assert.IsFalse(frUrl.IsUrl);
|
||||
}
|
||||
|
||||
// TODO: We need a lot of tests here, the above was just to get started with being able to unit test this method
|
||||
// * variant URLs without domains assigned, what happens?
|
||||
// * variant URLs with domains assigned, but also having more languages installed than there are domains/cultures assigned
|
||||
// * variant URLs with an ancestor culture unpublished
|
||||
// * invariant URLs with ancestors as variants
|
||||
// * ... probably a lot more
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Logging;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedRouterTests
|
||||
{
|
||||
private PublishedRouter CreatePublishedRouter(IUmbracoContextAccessor umbracoContextAccessor)
|
||||
=> new PublishedRouter(
|
||||
Microsoft.Extensions.Options.Options.Create(new WebRoutingSettings()),
|
||||
new ContentFinderCollection(() => Enumerable.Empty<IContentFinder>()),
|
||||
new TestLastChanceFinder(),
|
||||
new TestVariationContextAccessor(),
|
||||
Mock.Of<IProfilingLogger>(),
|
||||
Mock.Of<ILogger<PublishedRouter>>(),
|
||||
Mock.Of<IPublishedUrlProvider>(),
|
||||
Mock.Of<IRequestAccessor>(),
|
||||
Mock.Of<IPublishedValueFallback>(),
|
||||
Mock.Of<IFileService>(),
|
||||
Mock.Of<IContentTypeService>(),
|
||||
umbracoContextAccessor,
|
||||
Mock.Of<IEventAggregator>());
|
||||
|
||||
private IUmbracoContextAccessor GetUmbracoContextAccessor()
|
||||
{
|
||||
var uri = new Uri("http://example.com");
|
||||
var umbracoContext = Mock.Of<IUmbracoContext>(x => x.CleanedUmbracoUrl == uri);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
return umbracoContextAccessor;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ConfigureRequest_Returns_False_Without_HasPublishedContent()
|
||||
{
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor();
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var request = await publishedRouter.CreateRequestAsync(umbracoContextAccessor.GetRequiredUmbracoContext().CleanedUmbracoUrl);
|
||||
var result = publishedRouter.BuildRequest(request);
|
||||
|
||||
Assert.IsFalse(result.Success());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ConfigureRequest_Returns_False_When_IsRedirect()
|
||||
{
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor();
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var request = await publishedRouter.CreateRequestAsync(umbracoContextAccessor.GetRequiredUmbracoContext().CleanedUmbracoUrl);
|
||||
var content = GetPublishedContentMock();
|
||||
request.SetPublishedContent(content.Object);
|
||||
request.SetCulture("en-AU");
|
||||
request.SetRedirect("/hello");
|
||||
var result = publishedRouter.BuildRequest(request);
|
||||
|
||||
Assert.IsFalse(result.Success());
|
||||
}
|
||||
|
||||
private Mock<IPublishedContent> GetPublishedContentMock()
|
||||
{
|
||||
var pc = new Mock<IPublishedContent>();
|
||||
pc.Setup(content => content.Id).Returns(1);
|
||||
pc.Setup(content => content.Name).Returns("test");
|
||||
pc.Setup(content => content.CreateDate).Returns(DateTime.Now);
|
||||
pc.Setup(content => content.UpdateDate).Returns(DateTime.Now);
|
||||
pc.Setup(content => content.Path).Returns("-1,1");
|
||||
pc.Setup(content => content.Parent).Returns(() => null);
|
||||
pc.Setup(content => content.Properties).Returns(new Collection<IPublishedProperty>());
|
||||
pc.Setup(content => content.ContentType).Returns(new PublishedContentType(Guid.NewGuid(), 22, "anything", PublishedItemType.Content, Enumerable.Empty<string>(), Enumerable.Empty<PublishedPropertyType>(), ContentVariation.Nothing));
|
||||
return pc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class UrlProviderWithHideTopLevelNodeFromPathTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
GlobalSettings.HideTopLevelNodeFromPath = true;
|
||||
}
|
||||
|
||||
[TestCase(1046, "/")]
|
||||
[TestCase(1173, "/sub1/")]
|
||||
[TestCase(1174, "/sub1/sub2/")]
|
||||
[TestCase(1176, "/sub1/sub-3/")]
|
||||
[TestCase(1177, "/sub1/custom-sub-1/")]
|
||||
[TestCase(1178, "/sub1/custom-sub-2/")]
|
||||
[TestCase(1175, "/sub-2/")]
|
||||
[TestCase(1172, "/test-page/")] // not hidden because not first root
|
||||
public void Get_Url_Hiding_Top_Level(int nodeId, string niceUrlMatch)
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var result = urlProvider.GetUrl(nodeId);
|
||||
Assert.AreEqual(niceUrlMatch, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class UrlProviderWithoutHideTopLevelNodeFromPathTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private const string CacheKeyPrefix = "NuCache.ContentCache.RouteByContent";
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
|
||||
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
}
|
||||
|
||||
private void PopulateCache(string culture = "fr-FR")
|
||||
{
|
||||
var dataTypes = GetDefaultDataTypes();
|
||||
var propertyDataTypes = new Dictionary<string, IDataType>
|
||||
{
|
||||
// we only have one data type for this test which will be resolved with string empty.
|
||||
[string.Empty] = dataTypes[0]
|
||||
};
|
||||
var contentType1 = new ContentType(ShortStringHelper, -1);
|
||||
|
||||
ContentData rootData = new ContentDataBuilder()
|
||||
.WithName("Page" + Guid.NewGuid())
|
||||
.WithCultureInfos(new Dictionary<string, CultureVariation>
|
||||
{
|
||||
[culture] = new CultureVariation
|
||||
{
|
||||
Name = "root",
|
||||
IsDraft = true,
|
||||
Date = DateTime.Now,
|
||||
UrlSegment = "root"
|
||||
},
|
||||
})
|
||||
.Build(ShortStringHelper, propertyDataTypes, contentType1, "alias");
|
||||
|
||||
ContentNodeKit root = ContentNodeKitBuilder.CreateWithContent(
|
||||
contentType1.Id,
|
||||
9876, $"-1,9876",
|
||||
draftData: rootData,
|
||||
publishedData: rootData);
|
||||
|
||||
ContentData parentData = new ContentDataBuilder()
|
||||
.WithName("Page" + Guid.NewGuid())
|
||||
.WithCultureInfos(new Dictionary<string, CultureVariation>
|
||||
{
|
||||
[culture] = new CultureVariation
|
||||
{
|
||||
Name = "home",
|
||||
IsDraft = true,
|
||||
Date = DateTime.Now,
|
||||
UrlSegment = "home"
|
||||
},
|
||||
})
|
||||
.Build();
|
||||
|
||||
ContentNodeKit parent = ContentNodeKitBuilder.CreateWithContent(
|
||||
contentType1.Id,
|
||||
5432, $"-1,9876,5432",
|
||||
parentContentId: 9876,
|
||||
draftData: parentData,
|
||||
publishedData: parentData);
|
||||
|
||||
ContentData contentData = new ContentDataBuilder()
|
||||
.WithName("Page" + Guid.NewGuid())
|
||||
.WithCultureInfos(new Dictionary<string, CultureVariation>
|
||||
{
|
||||
[culture] = new CultureVariation
|
||||
{
|
||||
Name = "name-fr2",
|
||||
IsDraft = true,
|
||||
Date = DateTime.Now,
|
||||
UrlSegment = "test-fr"
|
||||
},
|
||||
})
|
||||
.Build();
|
||||
|
||||
ContentNodeKit content = ContentNodeKitBuilder.CreateWithContent(
|
||||
contentType1.Id,
|
||||
1234, $"-1,9876,5432,1234",
|
||||
parentContentId: 5432,
|
||||
draftData: contentData,
|
||||
publishedData: contentData);
|
||||
|
||||
InitializedCache(new[] { root, parent, content }, new[] { contentType1 }, dataTypes: dataTypes);
|
||||
}
|
||||
|
||||
private void SetDomains1()
|
||||
{
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("http://example.us/") {Id = 1, RootContentId = 9876, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://example.fr/") {Id = 2, RootContentId = 9876, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This checks that when we retrieve a NiceUrl for multiple items that there are no issues with cache overlap
|
||||
/// and that they are all cached correctly.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Ensure_Cache_Is_Correct()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = false };
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var samples = new Dictionary<int, string> {
|
||||
{ 1046, "/home" },
|
||||
{ 1173, "/home/sub1" },
|
||||
{ 1174, "/home/sub1/sub2" },
|
||||
{ 1176, "/home/sub1/sub-3" },
|
||||
{ 1177, "/home/sub1/custom-sub-1" },
|
||||
{ 1178, "/home/sub1/custom-sub-2" },
|
||||
{ 1175, "/home/sub-2" },
|
||||
{ 1172, "/test-page" }
|
||||
};
|
||||
|
||||
foreach (var sample in samples)
|
||||
{
|
||||
var result = urlProvider.GetUrl(sample.Key);
|
||||
Assert.AreEqual(sample.Value, result);
|
||||
}
|
||||
|
||||
var randomSample = new KeyValuePair<int, string>(1177, "/home/sub1/custom-sub-1");
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
var result = urlProvider.GetUrl(randomSample.Key);
|
||||
Assert.AreEqual(randomSample.Value, result);
|
||||
}
|
||||
|
||||
|
||||
var cache = (FastDictionaryAppCache)umbracoContext.PublishedSnapshot.ElementsCache;
|
||||
var cachedRoutes = cache.Keys.Where(x => x.StartsWith(CacheKeyPrefix)).ToList();
|
||||
Assert.AreEqual(8, cachedRoutes.Count);
|
||||
|
||||
foreach (var sample in samples)
|
||||
{
|
||||
var cacheKey = $"{CacheKeyPrefix}[P:{sample.Key}]";
|
||||
var found = (string)cache.Get(cacheKey);
|
||||
Assert.IsNotNull(found);
|
||||
Assert.AreEqual(sample.Value, found);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(1046, "/home/")]
|
||||
[TestCase(1173, "/home/sub1/")]
|
||||
[TestCase(1174, "/home/sub1/sub2/")]
|
||||
[TestCase(1176, "/home/sub1/sub-3/")]
|
||||
[TestCase(1177, "/home/sub1/custom-sub-1/")]
|
||||
[TestCase(1178, "/home/sub1/custom-sub-2/")]
|
||||
[TestCase(1175, "/home/sub-2/")]
|
||||
[TestCase(1172, "/test-page/")]
|
||||
public void Get_Url_Not_Hiding_Top_Level(int nodeId, string niceUrlMatch)
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var result = urlProvider.GetUrl(nodeId);
|
||||
Assert.AreEqual(niceUrlMatch, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("fr-FR", ExpectedResult = "#")] // Non default cultures cannot return urls
|
||||
[TestCase("en-US", ExpectedResult = "/root/home/test-fr/")] // Default culture can return urls
|
||||
public string Get_Url_For_Culture_Variant_Without_Domains_Non_Current_Url(string culture)
|
||||
{
|
||||
const string currentUri = "http://example.us/test";
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
PopulateCache(culture);
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(currentUri);
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
|
||||
//even though we are asking for a specific culture URL, there are no domains assigned so all that can be returned is a normal relative URL.
|
||||
var url = urlProvider.GetUrl(1234, culture: culture);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This tests DefaultUrlProvider.GetUrl with a specific culture when the current URL is the culture specific domain
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_Url_For_Culture_Variant_With_Current_Url()
|
||||
{
|
||||
const string currentUri = "http://example.fr/test";
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
PopulateCache();
|
||||
|
||||
SetDomains1();
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(currentUri);
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var url = urlProvider.GetUrl(1234, culture: "fr-FR");
|
||||
|
||||
Assert.AreEqual("/home/test-fr/", url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This tests DefaultUrlProvider.GetUrl with a specific culture when the current URL is not the culture specific domain
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Get_Url_For_Culture_Variant_Non_Current_Url()
|
||||
{
|
||||
const string currentUri = "http://example.us/test";
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
PopulateCache();
|
||||
|
||||
SetDomains1();
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(currentUri);
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
var url = urlProvider.GetUrl(1234, culture: "fr-FR");
|
||||
|
||||
//the current uri is not the culture specific domain we want, so the result is an absolute path to the culture specific domain
|
||||
Assert.AreEqual("http://example.fr/home/test-fr/", url);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Url_Relative_Or_Absolute()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://example.com/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
Assert.AreEqual("/home/sub1/custom-sub-1/", urlProvider.GetUrl(1177));
|
||||
|
||||
urlProvider.Mode = UrlMode.Absolute;
|
||||
Assert.AreEqual("http://example.com/home/sub1/custom-sub-1/", urlProvider.GetUrl(1177));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Url_Unpublished()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings();
|
||||
|
||||
string xml = PublishedContentXml.BaseWebTestXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://example.com/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
//mock the Umbraco settings that we need
|
||||
|
||||
Assert.AreEqual("#", urlProvider.GetUrl(999999));
|
||||
|
||||
urlProvider.Mode = UrlMode.Absolute;
|
||||
|
||||
Assert.AreEqual("#", urlProvider.GetUrl(999999));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
// TODO: We should be able to decouple this from the base db tests since we're just mocking the services now
|
||||
|
||||
[TestFixture]
|
||||
public class ContentFinderByAliasTests : UrlRoutingTestBase
|
||||
public abstract class UrlRoutingTestBase : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private PublishedContentType _publishedContentType;
|
||||
|
||||
protected override void Initialize()
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Initialize();
|
||||
base.Setup();
|
||||
|
||||
string xml = GetXmlContent(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
var properties = new[]
|
||||
{
|
||||
new PublishedPropertyType("umbracoUrlAlias", Constants.DataTypes.Textbox, false, ContentVariation.Nothing,
|
||||
new PropertyValueConverterCollection(Enumerable.Empty<IPropertyValueConverter>()),
|
||||
Mock.Of<IPublishedModelFactory>(),
|
||||
Mock.Of<IPublishedContentTypeFactory>()),
|
||||
};
|
||||
_publishedContentType = new PublishedContentType(Guid.NewGuid(), 0, "Doc", PublishedItemType.Content, Enumerable.Empty<string>(), properties, ContentVariation.Nothing);
|
||||
}
|
||||
|
||||
protected override PublishedContentType GetPublishedContentTypeByAlias(string alias)
|
||||
// Sets up the mock domain service
|
||||
protected override ServiceContext CreateServiceContext(IContentType[] contentTypes, IMediaType[] mediaTypes, IDataType[] dataTypes)
|
||||
{
|
||||
if (alias == "Doc") return _publishedContentType;
|
||||
return null;
|
||||
var serviceContext = base.CreateServiceContext(contentTypes, mediaTypes, dataTypes);
|
||||
|
||||
//setup mock domain service
|
||||
var domainService = Mock.Get(serviceContext.DomainService);
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com/"){Id = 1, LanguageId = LangDeId, RootContentId = 1001, LanguageIsoCode = "de-DE"},
|
||||
new UmbracoDomain("domain1.com/en"){Id = 2, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("domain1.com/fr"){Id = 3, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
|
||||
return serviceContext;
|
||||
}
|
||||
|
||||
[TestCase("/this/is/my/alias", 1001)]
|
||||
[TestCase("/anotheralias", 1001)]
|
||||
[TestCase("/page2/alias", 10011)]
|
||||
[TestCase("/2ndpagealias", 10011)]
|
||||
[TestCase("/only/one/alias", 100111)]
|
||||
[TestCase("/ONLY/one/Alias", 100111)]
|
||||
[TestCase("/alias43", 100121)]
|
||||
public async Task Lookup_By_Url_Alias(string urlAsString, int nodeMatch)
|
||||
{
|
||||
var umbracoContext = GetUmbracoContext(urlAsString);
|
||||
var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext));
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var lookup =
|
||||
new ContentFinderByUrlAlias(LoggerFactory.CreateLogger<ContentFinderByUrlAlias>(), Mock.Of<IPublishedValueFallback>(), VariationContextAccessor, GetUmbracoContextAccessor(umbracoContext));
|
||||
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(frequest.PublishedContent.Id, nodeMatch);
|
||||
}
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
protected virtual string GetXmlContent(int templateId)
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Doc ANY>
|
||||
<!ATTLIST Doc id ID #REQUIRED>
|
||||
@@ -147,7 +134,12 @@ namespace Umbraco.Tests.Routing
|
||||
</Doc>
|
||||
</Doc>
|
||||
</root>";
|
||||
}
|
||||
|
||||
public const int LangDeId = 333;
|
||||
public const int LangEngId = 334;
|
||||
public const int LangFrId = 335;
|
||||
public const int LangCzId = 336;
|
||||
public const int LangNlId = 337;
|
||||
public const int LangDkId = 338;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
@@ -13,77 +14,83 @@ using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Tests.LegacyXmlPublishedCache;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class UrlsProviderWithDomainsTests : UrlRoutingTestBase
|
||||
{
|
||||
private IUmbracoContextAccessor UmbracoContextAccessor { get; } = new TestUmbracoContextAccessor();
|
||||
protected override void Compose()
|
||||
{
|
||||
base.Compose();
|
||||
private const string CacheKeyPrefix = "NuCache.ContentCache.RouteByContent";
|
||||
|
||||
Builder.Services.AddUnique(Mock.Of<IDomainService>());
|
||||
Builder.Services.AddTransient<ISiteDomainMapper, SiteDomainMapper>();
|
||||
private void SetDomains1()
|
||||
{
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com") {Id = 1, LanguageId = LangFrId, RootContentId = 1001, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
void SetDomains1()
|
||||
private void SetDomains2()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("domain1.com") {Id = 1, LanguageId = LangFrId, RootContentId = 1001, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/foo") {Id = 1, LanguageId = LangFrId, RootContentId = 1001, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
void SetDomains2()
|
||||
private void SetDomains3()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/foo") {Id = 1, LanguageId = LangFrId, RootContentId = 1001, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangFrId, RootContentId = 10011, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
void SetDomains3()
|
||||
private void SetDomains4()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangFrId, RootContentId = 10011, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1.com/en") {Id = 2, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1.com/fr") {Id = 3, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain3.com/") {Id = 4, LanguageId = LangEngId, RootContentId = 1003, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/en") {Id = 5, LanguageId = LangEngId, RootContentId = 10031, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/fr") {Id = 6, LanguageId = LangFrId, RootContentId = 10032, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
void SetDomains4()
|
||||
private void SetDomains5()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain3.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1003, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10031, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10032, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
void SetDomains5()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1a.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1b.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain1a.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain1b.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain3.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10031, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/fr") {Id = 1, LanguageId = LangFrId, RootContentId = 10032, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/en") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1a.com/en") {Id = 2, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1b.com/en") {Id = 3, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain1.com/fr") {Id = 4, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain1a.com/fr") {Id = 5, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain1b.com/fr") {Id = 6, LanguageId = LangFrId, RootContentId = 10012, LanguageIsoCode = "fr-FR"},
|
||||
new UmbracoDomain("http://domain3.com/en") {Id = 7, LanguageId = LangEngId, RootContentId = 10031, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain3.com/fr") {Id = 8, LanguageId = LangFrId, RootContentId = 10032, LanguageIsoCode = "fr-FR"}
|
||||
});
|
||||
}
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Doc ANY>
|
||||
<!ATTLIST Doc id ID #REQUIRED>
|
||||
@@ -162,7 +169,6 @@ namespace Umbraco.Tests.Routing
|
||||
</Doc>
|
||||
</Doc>
|
||||
</root>";
|
||||
}
|
||||
|
||||
// with one simple domain "domain1.com"
|
||||
// basic tests
|
||||
@@ -179,21 +185,18 @@ namespace Umbraco.Tests.Routing
|
||||
[TestCase(10011, "https://domain1.com", false, "/1001-1/")]
|
||||
public void Get_Url_SimpleDomain(int nodeId, string currentUrl, bool absolute, string expected)
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains1();
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var currentUri = new Uri(currentUrl);
|
||||
var mode = absolute ? UrlMode.Absolute : UrlMode.Auto;
|
||||
var result = publishedUrlProvider.GetUrl(nodeId, mode, current: currentUri);
|
||||
var result = urlProvider.GetUrl(nodeId, mode, current: currentUri);
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
@@ -212,21 +215,18 @@ namespace Umbraco.Tests.Routing
|
||||
[TestCase(10011, "https://domain1.com", false, "http://domain1.com/foo/1001-1/")]
|
||||
public void Get_Url_SimpleWithSchemeAndPath(int nodeId, string currentUrl, bool absolute, string expected)
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains2();
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var currentUri = new Uri(currentUrl);
|
||||
var mode = absolute ? UrlMode.Absolute : UrlMode.Auto;
|
||||
var result = publishedUrlProvider.GetUrl(nodeId, mode, current : currentUri);
|
||||
var result = urlProvider.GetUrl(nodeId, mode, current: currentUri);
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
@@ -237,21 +237,18 @@ namespace Umbraco.Tests.Routing
|
||||
[TestCase(1002, "http://domain1.com", false, "/1002/")]
|
||||
public void Get_Url_DeepDomain(int nodeId, string currentUrl, bool absolute, string expected)
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains3();
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
var currentUri = new Uri(currentUrl);
|
||||
var mode = absolute ? UrlMode.Absolute : UrlMode.Auto;
|
||||
var result = publishedUrlProvider.GetUrl(nodeId, mode, current : currentUri);
|
||||
var result = urlProvider.GetUrl(nodeId, mode, current: currentUri);
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
@@ -268,152 +265,130 @@ namespace Umbraco.Tests.Routing
|
||||
[TestCase(100321, "http://domain3.com", false, "/fr/1003-2-1/")]
|
||||
public void Get_Url_NestedDomains(int nodeId, string currentUrl, bool absolute, string expected)
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(
|
||||
Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains4();
|
||||
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
|
||||
var currentUri = new Uri(currentUrl);
|
||||
var mode = absolute ? UrlMode.Absolute : UrlMode.Auto;
|
||||
var result = publishedUrlProvider.GetUrl(nodeId, mode, current : currentUri);
|
||||
var result = urlProvider.GetUrl(nodeId, mode, current: currentUri);
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Url_DomainsAndCache()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(
|
||||
Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains4();
|
||||
|
||||
string ignore;
|
||||
ignore = publishedUrlProvider.GetUrl(1001, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(10011, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(100111, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(10012, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(100121, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(10013, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(1002, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(1001, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(10011, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(100111, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
ignore = publishedUrlProvider.GetUrl(1002, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var cache = umbracoContext.Content as PublishedContentCache;
|
||||
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
|
||||
var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("/test");
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
|
||||
|
||||
string ignore;
|
||||
ignore = urlProvider.GetUrl(1001, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(10011, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(100111, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(10012, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(100121, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(10013, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(1002, UrlMode.Auto, current: new Uri("http://domain1.com"));
|
||||
ignore = urlProvider.GetUrl(1001, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
ignore = urlProvider.GetUrl(10011, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
ignore = urlProvider.GetUrl(100111, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
ignore = urlProvider.GetUrl(1002, UrlMode.Auto, current: new Uri("http://domain2.com"));
|
||||
|
||||
|
||||
var cache = (FastDictionaryAppCache)umbracoContext.PublishedSnapshot.ElementsCache;
|
||||
var cachedRoutes = cache.Keys.Where(x => x.StartsWith(CacheKeyPrefix)).ToList();
|
||||
Assert.AreEqual(7, cachedRoutes.Count);
|
||||
|
||||
var cachedIds = cache.RoutesCache.GetCachedIds();
|
||||
Assert.AreEqual(0, cachedIds.Count);
|
||||
//var cachedIds = cache.RoutesCache.GetCachedIds();
|
||||
//Assert.AreEqual(0, cachedIds.Count);
|
||||
|
||||
CheckRoute(cachedRoutes, cachedIds, 1001, "1001/");
|
||||
CheckRoute(cachedRoutes, cachedIds, 10011, "10011/");
|
||||
CheckRoute(cachedRoutes, cachedIds, 100111, "10011/1001-1-1");
|
||||
CheckRoute(cachedRoutes, cachedIds, 10012, "10012/");
|
||||
CheckRoute(cachedRoutes, cachedIds, 100121, "10012/1001-2-1");
|
||||
CheckRoute(cachedRoutes, cachedIds, 10013, "1001/1001-3");
|
||||
CheckRoute(cachedRoutes, cachedIds, 1002, "/1002");
|
||||
CheckRoute(cache, 1001, "1001/");
|
||||
CheckRoute(cache, 10011, "10011/");
|
||||
CheckRoute(cache, 100111, "10011/1001-1-1");
|
||||
CheckRoute(cache, 10012, "10012/");
|
||||
CheckRoute(cache, 100121, "10012/1001-2-1");
|
||||
CheckRoute(cache, 10013, "1001/1001-3");
|
||||
CheckRoute(cache, 1002, "/1002");
|
||||
|
||||
// use the cache
|
||||
Assert.AreEqual("/", publishedUrlProvider.GetUrl(1001, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/en/", publishedUrlProvider.GetUrl(10011, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/en/1001-1-1/", publishedUrlProvider.GetUrl(100111, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/fr/", publishedUrlProvider.GetUrl(10012, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/fr/1001-2-1/", publishedUrlProvider.GetUrl(100121, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/1001-3/", publishedUrlProvider.GetUrl(10013, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/1002/", publishedUrlProvider.GetUrl(1002, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/", urlProvider.GetUrl(1001, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/en/", urlProvider.GetUrl(10011, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/en/1001-1-1/", urlProvider.GetUrl(100111, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/fr/", urlProvider.GetUrl(10012, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/fr/1001-2-1/", urlProvider.GetUrl(100121, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/1001-3/", urlProvider.GetUrl(10013, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
Assert.AreEqual("/1002/", urlProvider.GetUrl(1002, UrlMode.Auto, current: new Uri("http://domain1.com")));
|
||||
|
||||
Assert.AreEqual("http://domain1.com/fr/1001-2-1/", publishedUrlProvider.GetUrl(100121, UrlMode.Auto, current: new Uri("http://domain2.com")));
|
||||
Assert.AreEqual("http://domain1.com/fr/1001-2-1/", urlProvider.GetUrl(100121, UrlMode.Auto, current: new Uri("http://domain2.com")));
|
||||
}
|
||||
|
||||
private static void CheckRoute(IDictionary<int, string> routes, IDictionary<string, int> ids, int id, string route)
|
||||
private static void CheckRoute(FastDictionaryAppCache routes, int id, string route)
|
||||
{
|
||||
Assert.IsTrue(routes.ContainsKey(id));
|
||||
Assert.AreEqual(route, routes[id]);
|
||||
Assert.IsFalse(ids.ContainsKey(route));
|
||||
var cacheKey = $"{CacheKeyPrefix}[P:{id}]";
|
||||
var found = (string)routes.Get(cacheKey);
|
||||
Assert.IsNotNull(found);
|
||||
Assert.AreEqual(route, found);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Url_Relative_Or_Absolute()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("http://domain1.com/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(
|
||||
Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains4();
|
||||
|
||||
Assert.AreEqual("/en/1001-1-1/", publishedUrlProvider.GetUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1/", publishedUrlProvider.GetUrl(100311));
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
publishedUrlProvider.Mode = UrlMode.Absolute;
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://domain1.com/test");
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1/", publishedUrlProvider.GetUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1/", publishedUrlProvider.GetUrl(100311));
|
||||
|
||||
Assert.AreEqual("/en/1001-1-1/", urlProvider.GetUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1/", urlProvider.GetUrl(100311));
|
||||
|
||||
urlProvider.Mode = UrlMode.Absolute;
|
||||
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1/", urlProvider.GetUrl(100111));
|
||||
Assert.AreEqual("http://domain3.com/en/1003-1-1/", urlProvider.GetUrl(100311));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Url_Alternate()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
|
||||
var umbracoContext = GetUmbracoContext("http://domain1.com/en/test", 1111, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);
|
||||
var urlProvider = new DefaultUrlProvider(
|
||||
Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
SetDomains5();
|
||||
|
||||
var url = publishedUrlProvider.GetUrl(100111, UrlMode.Absolute);
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor("http://domain1.com/en/test");
|
||||
UrlProvider urlProvider = GetUrlProvider(umbracoContextAccessor, requestHandlerSettings, new WebRoutingSettings(), out UriUtility uriUtility);
|
||||
|
||||
|
||||
var url = urlProvider.GetUrl(100111, UrlMode.Absolute);
|
||||
Assert.AreEqual("http://domain1.com/en/1001-1-1/", url);
|
||||
|
||||
var result = publishedUrlProvider.GetOtherUrls(100111).ToArray();
|
||||
var result = urlProvider.GetOtherUrls(100111).ToArray();
|
||||
|
||||
foreach (var x in result) Console.WriteLine(x);
|
||||
foreach (var x in result)
|
||||
Console.WriteLine(x);
|
||||
|
||||
Assert.AreEqual(2, result.Length);
|
||||
Assert.AreEqual(result[0].Text, "http://domain1b.com/en/1001-1-1/");
|
||||
Assert.AreEqual(result[1].Text, "http://domain1a.com/en/1001-1-1/");
|
||||
}
|
||||
|
||||
private IPublishedUrlProvider GetPublishedUrlProvider(IUmbracoContext umbracoContext, DefaultUrlProvider urlProvider)
|
||||
{
|
||||
var webRoutingSettings = new WebRoutingSettings();
|
||||
return new UrlProvider(
|
||||
new TestUmbracoContextAccessor(umbracoContext),
|
||||
Microsoft.Extensions.Options.Options.Create(webRoutingSettings),
|
||||
new UrlProviderCollection(new []{urlProvider}),
|
||||
new MediaUrlProviderCollection(Enumerable.Empty<IMediaUrlProvider>()),
|
||||
Mock.Of<IVariationContextAccessor>()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,19 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Tests.Common;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Tests.LegacyXmlPublishedCache;
|
||||
|
||||
namespace Umbraco.Tests.Routing
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
|
||||
{
|
||||
[TestFixture]
|
||||
public class UrlsWithNestedDomains : UrlRoutingTestBase
|
||||
@@ -25,61 +27,60 @@ namespace Umbraco.Tests.Routing
|
||||
// using the closest domain to the node - here we test that if we request
|
||||
// a non-canonical route, it is not cached / the cache is not polluted
|
||||
|
||||
protected override void Compose()
|
||||
{
|
||||
base.Compose();
|
||||
Builder.Services.AddUnique(Mock.Of<IDomainService>());
|
||||
Builder.Services.AddTransient<ISiteDomainMapper, SiteDomainMapper>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DoNotPolluteCache()
|
||||
{
|
||||
var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true };
|
||||
var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false };
|
||||
GlobalSettings.HideTopLevelNodeFromPath = false;
|
||||
|
||||
SetDomains1();
|
||||
|
||||
const string url = "http://domain1.com/1001-1/1001-1-1";
|
||||
|
||||
// get the nice URL for 100111
|
||||
var umbracoContext = GetUmbracoContext(url, 9999, globalSettings: globalSettings);
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(umbracoContext);
|
||||
var umbracoContextAccessor = GetUmbracoContextAccessor(url);
|
||||
var umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
|
||||
var urlProvider = new DefaultUrlProvider(
|
||||
Microsoft.Extensions.Options.Options.Create(requestHandlerSettings),
|
||||
LoggerFactory.CreateLogger<DefaultUrlProvider>(),
|
||||
new SiteDomainMapper(), umbracoContextAccessor, UriUtility);
|
||||
Mock.Of<ILogger<DefaultUrlProvider>>(),
|
||||
new SiteDomainMapper(),
|
||||
umbracoContextAccessor,
|
||||
new UriUtility(Mock.Of<IHostingEnvironment>()),
|
||||
Mock.Of<ILocalizationService>());
|
||||
var publishedUrlProvider = GetPublishedUrlProvider(umbracoContext, urlProvider);
|
||||
|
||||
Assert.AreEqual("http://domain2.com/1001-1-1/", publishedUrlProvider.GetUrl(100111, UrlMode.Absolute));
|
||||
string absUrl = publishedUrlProvider.GetUrl(100111, UrlMode.Absolute);
|
||||
Assert.AreEqual("http://domain2.com/1001-1-1/", absUrl);
|
||||
|
||||
const string cacheKeyPrefix = "NuCache.ContentCache.RouteByContent";
|
||||
|
||||
// check that the proper route has been cached
|
||||
var cache = umbracoContext.Content as PublishedContentCache;
|
||||
if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
|
||||
var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
|
||||
Assert.AreEqual("10011/1001-1-1", cachedRoutes[100111]);
|
||||
var cache = (FastDictionaryAppCache)umbracoContext.PublishedSnapshot.ElementsCache;
|
||||
|
||||
var cachedRoutes = cache.Keys.Where(x => x.StartsWith(cacheKeyPrefix)).ToList();
|
||||
var cacheKey = $"{cacheKeyPrefix}[P:100111]";
|
||||
Assert.AreEqual("10011/1001-1-1", cache.Get(cacheKey));
|
||||
|
||||
// route a rogue URL
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
publishedRouter.FindDomain(frequest);
|
||||
Assert.IsTrue(frequest.HasDomain());
|
||||
|
||||
// check that it's been routed
|
||||
var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger<ContentFinderByUrl>(), GetUmbracoContextAccessor(umbracoContext));
|
||||
var lookup = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = lookup.TryFindContent(frequest);
|
||||
Assert.IsTrue(result);
|
||||
Assert.AreEqual(100111, frequest.PublishedContent.Id);
|
||||
|
||||
// has the cache been polluted?
|
||||
cachedRoutes = cache.RoutesCache.GetCachedRoutes();
|
||||
Assert.AreEqual("10011/1001-1-1", cachedRoutes[100111]); // no
|
||||
//Assert.AreEqual("1001/1001-1/1001-1-1", cachedRoutes[100111]); // yes
|
||||
cachedRoutes = cache.Keys.Where(x => x.StartsWith(cacheKeyPrefix)).ToList();
|
||||
Assert.AreEqual("10011/1001-1-1", cache.Get(cacheKey)); // no
|
||||
|
||||
// what's the nice URL now?
|
||||
Assert.AreEqual("http://domain2.com/1001-1-1/", publishedUrlProvider.GetUrl(100111)); // good
|
||||
//Assert.AreEqual("http://domain1.com/1001-1/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111, true)); // bad
|
||||
}
|
||||
|
||||
private IPublishedUrlProvider GetPublishedUrlProvider(IUmbracoContext umbracoContext, object urlProvider)
|
||||
@@ -87,14 +88,16 @@ namespace Umbraco.Tests.Routing
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void SetDomains1()
|
||||
private void SetDomains1()
|
||||
{
|
||||
SetupDomainServiceMock(new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain2.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"}
|
||||
});
|
||||
var domainService = Mock.Get(DomainService);
|
||||
|
||||
domainService.Setup(service => service.GetAll(It.IsAny<bool>()))
|
||||
.Returns((bool incWildcards) => new[]
|
||||
{
|
||||
new UmbracoDomain("http://domain1.com/") {Id = 1, LanguageId = LangEngId, RootContentId = 1001, LanguageIsoCode = "en-US"},
|
||||
new UmbracoDomain("http://domain2.com/") {Id = 2, LanguageId = LangEngId, RootContentId = 10011, LanguageIsoCode = "en-US"}
|
||||
});
|
||||
}
|
||||
|
||||
private IPublishedUrlProvider GetPublishedUrlProvider(IUmbracoContext umbracoContext, DefaultUrlProvider urlProvider)
|
||||
@@ -103,15 +106,14 @@ namespace Umbraco.Tests.Routing
|
||||
return new UrlProvider(
|
||||
new TestUmbracoContextAccessor(umbracoContext),
|
||||
Microsoft.Extensions.Options.Options.Create(webRoutingSettings),
|
||||
new UrlProviderCollection(new []{urlProvider}),
|
||||
new MediaUrlProviderCollection(Enumerable.Empty<IMediaUrlProvider>()),
|
||||
new UrlProviderCollection(() => new[] { urlProvider }),
|
||||
new MediaUrlProviderCollection(() => Enumerable.Empty<IMediaUrlProvider>()),
|
||||
Mock.Of<IVariationContextAccessor>()
|
||||
);
|
||||
}
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
=> @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Doc ANY>
|
||||
<!ATTLIST Doc id ID #REQUIRED>
|
||||
@@ -190,6 +192,5 @@ namespace Umbraco.Tests.Routing
|
||||
</Doc>
|
||||
</Doc>
|
||||
</root>";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using AutoFixture.NUnit3;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Runtime;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Infrastructure.HostedServices;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
|
||||
namespace Umbraco.Tests.Scheduling
|
||||
{
|
||||
[TestFixture]
|
||||
class ContentVersionCleanupTest
|
||||
{
|
||||
[Test, AutoMoqData]
|
||||
public async Task ContentVersionCleanup_WhenNotEnabled_DoesNotCleanupWillRepeat(
|
||||
[Frozen] Mock<IOptionsMonitor<ContentSettings>> settings,
|
||||
[Frozen] Mock<IMainDom> mainDom,
|
||||
[Frozen] Mock<IServerRoleAccessor> serverRoleAccessor,
|
||||
[Frozen] Mock<IRuntimeState> runtimeState,
|
||||
[Frozen] Mock<IContentVersionService> cleanupService,
|
||||
ContentVersionCleanup sut)
|
||||
{
|
||||
settings.Setup(x => x.CurrentValue).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = false
|
||||
}
|
||||
});
|
||||
runtimeState.Setup(x => x.Level).Returns(RuntimeLevel.Run);
|
||||
mainDom.Setup(x => x.IsMainDom).Returns(true);
|
||||
serverRoleAccessor.Setup(x => x.CurrentServerRole).Returns(ServerRole.SchedulingPublisher);
|
||||
|
||||
await sut.PerformExecuteAsync(null);
|
||||
|
||||
cleanupService.Verify(x => x.PerformContentVersionCleanup(It.IsAny<DateTime>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public async Task ContentVersionCleanup_RuntimeLevelNotRun_DoesNotCleanupWillRepeat(
|
||||
[Frozen] Mock<IOptionsMonitor<ContentSettings>> settings,
|
||||
[Frozen] Mock<IMainDom> mainDom,
|
||||
[Frozen] Mock<IServerRoleAccessor> serverRoleAccessor,
|
||||
[Frozen] Mock<IRuntimeState> runtimeState,
|
||||
[Frozen] Mock<IContentVersionService> cleanupService,
|
||||
ContentVersionCleanup sut)
|
||||
{
|
||||
settings.Setup(x => x.CurrentValue).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true
|
||||
}
|
||||
});
|
||||
runtimeState.Setup(x => x.Level).Returns(RuntimeLevel.Unknown);
|
||||
mainDom.Setup(x => x.IsMainDom).Returns(true);
|
||||
serverRoleAccessor.Setup(x => x.CurrentServerRole).Returns(ServerRole.SchedulingPublisher);
|
||||
|
||||
await sut.PerformExecuteAsync(null);
|
||||
|
||||
cleanupService.Verify(x => x.PerformContentVersionCleanup(It.IsAny<DateTime>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public async Task ContentVersionCleanup_ServerRoleUnknown_DoesNotCleanupWillRepeat(
|
||||
[Frozen] Mock<IOptionsMonitor<ContentSettings>> settings,
|
||||
[Frozen] Mock<IMainDom> mainDom,
|
||||
[Frozen] Mock<IServerRoleAccessor> serverRoleAccessor,
|
||||
[Frozen] Mock<IRuntimeState> runtimeState,
|
||||
[Frozen] Mock<IContentVersionService> cleanupService,
|
||||
ContentVersionCleanup sut)
|
||||
{
|
||||
settings.Setup(x => x.CurrentValue).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true
|
||||
}
|
||||
});
|
||||
runtimeState.Setup(x => x.Level).Returns(RuntimeLevel.Run);
|
||||
mainDom.Setup(x => x.IsMainDom).Returns(true);
|
||||
serverRoleAccessor.Setup(x => x.CurrentServerRole).Returns(ServerRole.Unknown);
|
||||
|
||||
await sut.PerformExecuteAsync(null);
|
||||
|
||||
cleanupService.Verify(x => x.PerformContentVersionCleanup(It.IsAny<DateTime>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public async Task ContentVersionCleanup_NotMainDom_DoesNotCleanupWillNotRepeat(
|
||||
[Frozen] Mock<IOptionsMonitor<ContentSettings>> settings,
|
||||
[Frozen] Mock<IMainDom> mainDom,
|
||||
[Frozen] Mock<IServerRoleAccessor> serverRoleAccessor,
|
||||
[Frozen] Mock<IRuntimeState> runtimeState,
|
||||
[Frozen] Mock<IContentVersionService> cleanupService,
|
||||
ContentVersionCleanup sut)
|
||||
{
|
||||
settings.Setup(x => x.CurrentValue).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true
|
||||
}
|
||||
});
|
||||
|
||||
runtimeState.Setup(x => x.Level).Returns(RuntimeLevel.Run);
|
||||
mainDom.Setup(x => x.IsMainDom).Returns(false);
|
||||
serverRoleAccessor.Setup(x => x.CurrentServerRole).Returns(ServerRole.SchedulingPublisher);
|
||||
|
||||
await sut.PerformExecuteAsync(null);
|
||||
|
||||
cleanupService.Verify(x => x.PerformContentVersionCleanup(It.IsAny<DateTime>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public async Task ContentVersionCleanup_Enabled_DelegatesToCleanupService(
|
||||
[Frozen] Mock<IOptionsMonitor<ContentSettings>> settings,
|
||||
[Frozen] Mock<IMainDom> mainDom,
|
||||
[Frozen] Mock<IServerRoleAccessor> serverRoleAccessor,
|
||||
[Frozen] Mock<IRuntimeState> runtimeState,
|
||||
[Frozen] Mock<IContentVersionService> cleanupService,
|
||||
ContentVersionCleanup sut)
|
||||
{
|
||||
settings.Setup(x => x.CurrentValue).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true
|
||||
}
|
||||
});
|
||||
|
||||
runtimeState.Setup(x => x.Level).Returns(RuntimeLevel.Run);
|
||||
mainDom.Setup(x => x.IsMainDom).Returns(true);
|
||||
serverRoleAccessor.Setup(x => x.CurrentServerRole).Returns(ServerRole.SchedulingPublisher);
|
||||
|
||||
await sut.PerformExecuteAsync(null);
|
||||
|
||||
cleanupService.Verify(x => x.PerformContentVersionCleanup(It.IsAny<DateTime>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using AutoFixture.NUnit3;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.Persistence.Repositories;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Implement;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
internal class ContentVersionCleanupServiceTest
|
||||
{
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void PerformContentVersionCleanup_Always_RespectsDeleteRevisionsCancellation(
|
||||
[Frozen] Mock<IScopedNotificationPublisher> eventAggregator,
|
||||
[Frozen] Mock<IContentVersionCleanupPolicy> policy,
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
List<ContentVersionMeta> someHistoricVersions,
|
||||
DateTime aDateTime,
|
||||
ContentVersionService sut)
|
||||
{
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
eventAggregator.Setup(x => x.PublishCancelable(It.IsAny<ContentDeletingVersionsNotification>()))
|
||||
.Returns(true);
|
||||
|
||||
policy.Setup(x => x.Apply(aDateTime, someHistoricVersions))
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
// # Act
|
||||
IReadOnlyCollection<ContentVersionMeta> report = sut.PerformContentVersionCleanup(aDateTime);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
eventAggregator.Verify(x => x.PublishCancelable(It.IsAny<ContentDeletingVersionsNotification>()), Times.Exactly(someHistoricVersions.Count));
|
||||
Assert.AreEqual(0, report.Count);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[AutoMoqData]
|
||||
public void PerformContentVersionCleanup_Always_FiresDeletedVersionsForEachDeletedVersion(
|
||||
[Frozen] Mock<IScopedNotificationPublisher> eventAggregator,
|
||||
[Frozen] Mock<IContentVersionCleanupPolicy> policy,
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
List<ContentVersionMeta> someHistoricVersions,
|
||||
DateTime aDateTime,
|
||||
ContentVersionService sut)
|
||||
{
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
eventAggregator
|
||||
.Setup(x => x.PublishCancelable(It.IsAny<ICancelableNotification>()))
|
||||
.Returns(false);
|
||||
|
||||
policy.Setup(x => x.Apply(aDateTime, someHistoricVersions))
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
// # Act
|
||||
sut.PerformContentVersionCleanup(aDateTime);
|
||||
|
||||
eventAggregator.Verify(x => x.Publish(It.IsAny<ContentDeletedVersionsNotification>()), Times.Exactly(someHistoricVersions.Count));
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void PerformContentVersionCleanup_Always_ReturnsReportOfDeletedItems(
|
||||
[Frozen] Mock<IScopedNotificationPublisher> eventAggregator,
|
||||
[Frozen] Mock<IContentVersionCleanupPolicy> policy,
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
List<ContentVersionMeta> someHistoricVersions,
|
||||
DateTime aDateTime,
|
||||
ContentVersionService sut)
|
||||
{
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
eventAggregator
|
||||
.Setup(x => x.PublishCancelable(It.IsAny<ICancelableNotification>()))
|
||||
.Returns(false);
|
||||
|
||||
// # Act
|
||||
var report = sut.PerformContentVersionCleanup(aDateTime);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.Greater(report.Count, 0);
|
||||
Assert.AreEqual(someHistoricVersions.Count, report.Count);
|
||||
});
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void PerformContentVersionCleanup_Always_AdheresToCleanupPolicy(
|
||||
[Frozen] Mock<IScopedNotificationPublisher> eventAggregator,
|
||||
[Frozen] Mock<IContentVersionCleanupPolicy> policy,
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
List<ContentVersionMeta> someHistoricVersions,
|
||||
DateTime aDateTime,
|
||||
ContentVersionService sut)
|
||||
{
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
eventAggregator
|
||||
.Setup(x => x.PublishCancelable(It.IsAny<ICancelableNotification>()))
|
||||
.Returns(false);
|
||||
|
||||
policy.Setup(x => x.Apply(It.IsAny<DateTime>(), It.IsAny<IEnumerable<ContentVersionMeta>>()))
|
||||
.Returns<DateTime, IEnumerable<ContentVersionMeta>>((_, items) => items.Take(1));
|
||||
|
||||
// # Act
|
||||
var report = sut.PerformContentVersionCleanup(aDateTime);
|
||||
|
||||
Debug.Assert(someHistoricVersions.Count > 1);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
policy.Verify(x => x.Apply(aDateTime, someHistoricVersions), Times.Once);
|
||||
Assert.AreEqual(someHistoricVersions.First(), report.Single());
|
||||
});
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// For v9 this just needs a rewrite, no static events, no service location etc
|
||||
/// </remarks>
|
||||
[Test, AutoMoqData]
|
||||
public void PerformContentVersionCleanup_HasVersionsToDelete_CallsDeleteOnRepositoryWithFilteredSet(
|
||||
[Frozen] Mock<IScopedNotificationPublisher> eventAggregator,
|
||||
[Frozen] Mock<IContentVersionCleanupPolicy> policy,
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
List<ContentVersionMeta> someHistoricVersions,
|
||||
DateTime aDateTime,
|
||||
ContentVersionService sut)
|
||||
{
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(someHistoricVersions);
|
||||
|
||||
eventAggregator
|
||||
.Setup(x => x.PublishCancelable(It.IsAny<ICancelableNotification>()))
|
||||
.Returns(false);
|
||||
|
||||
var filteredSet = someHistoricVersions.Take(1);
|
||||
|
||||
policy.Setup(x => x.Apply(It.IsAny<DateTime>(), It.IsAny<IEnumerable<ContentVersionMeta>>()))
|
||||
.Returns<DateTime, IEnumerable<ContentVersionMeta>>((_, items) => filteredSet);
|
||||
|
||||
// # Act
|
||||
var report = sut.PerformContentVersionCleanup(aDateTime);
|
||||
|
||||
Debug.Assert(someHistoricVersions.Any());
|
||||
|
||||
var expectedId = filteredSet.First().VersionId;
|
||||
|
||||
documentVersionRepository.Verify(x => x.DeleteVersions(It.Is<IEnumerable<int>>(y => y.Single() == expectedId)), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AutoFixture.NUnit3;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Persistence.Repositories;
|
||||
using Umbraco.Cms.Infrastructure.Services.Implement;
|
||||
using Umbraco.Cms.Tests.UnitTests.AutoFixture;
|
||||
using ContentVersionCleanupPolicySettings = Umbraco.Cms.Core.Models.ContentVersionCleanupPolicySettings;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
public class DefaultContentVersionCleanupPolicyTest
|
||||
{
|
||||
[Test, AutoMoqData]
|
||||
public void Apply_AllOlderThanKeepSettings_AllVersionsReturned(
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
[Frozen] Mock<IOptions<ContentSettings>> contentSettings,
|
||||
DefaultContentVersionCleanupPolicy sut)
|
||||
{
|
||||
var versionId = 0;
|
||||
|
||||
var historicItems = new List<ContentVersionMeta>
|
||||
{
|
||||
new ContentVersionMeta(versionId: ++versionId, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: ++versionId, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
};
|
||||
|
||||
contentSettings.Setup(x => x.Value).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new Cms.Core.Configuration.Models.ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 0,
|
||||
KeepLatestVersionPerDayForDays = 0
|
||||
}
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetCleanupPolicies())
|
||||
.Returns(Array.Empty<ContentVersionCleanupPolicySettings>());
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(historicItems);
|
||||
|
||||
var results = sut.Apply(DateTime.Today, historicItems).ToList();
|
||||
|
||||
Assert.AreEqual(2, results.Count);
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void Apply_OverlappingKeepSettings_KeepAllVersionsNewerThanDaysTakesPriority(
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
[Frozen] Mock<IOptions<ContentSettings>> contentSettings,
|
||||
DefaultContentVersionCleanupPolicy sut)
|
||||
{
|
||||
var versionId = 0;
|
||||
|
||||
var historicItems = new List<ContentVersionMeta>
|
||||
{
|
||||
new ContentVersionMeta(versionId: ++versionId, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: ++versionId, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
};
|
||||
|
||||
contentSettings.Setup(x => x.Value).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new Cms.Core.Configuration.Models.ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 2,
|
||||
KeepLatestVersionPerDayForDays = 2
|
||||
}
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetCleanupPolicies())
|
||||
.Returns(Array.Empty<ContentVersionCleanupPolicySettings>());
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(historicItems);
|
||||
|
||||
var results = sut.Apply(DateTime.Today, historicItems).ToList();
|
||||
|
||||
Assert.AreEqual(0, results.Count);
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void Apply_WithinInKeepLatestPerDay_ReturnsSinglePerContentPerDay(
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
[Frozen] Mock<IOptions<ContentSettings>> contentSettings,
|
||||
DefaultContentVersionCleanupPolicy sut)
|
||||
{
|
||||
var historicItems = new List<ContentVersionMeta>
|
||||
{
|
||||
new ContentVersionMeta(versionId: 1, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 2, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 3, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
|
||||
new ContentVersionMeta(versionId: 4, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddDays(-1).AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 5, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddDays(-1).AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 6, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddDays(-1).AddHours(-1), false, false, false, null),
|
||||
// another content
|
||||
new ContentVersionMeta(versionId: 7, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 8, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 9, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
};
|
||||
|
||||
|
||||
contentSettings.Setup(x => x.Value).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new Cms.Core.Configuration.Models.ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 0,
|
||||
KeepLatestVersionPerDayForDays = 3
|
||||
}
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetCleanupPolicies())
|
||||
.Returns(Array.Empty<ContentVersionCleanupPolicySettings>());
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(historicItems);
|
||||
|
||||
var results = sut.Apply(DateTime.Today, historicItems).ToList();
|
||||
|
||||
// Keep latest per day for 3 days per content type
|
||||
// 2 content types, one of which has 2 days of entries, the other only a single day
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(6, results.Count);
|
||||
Assert.AreEqual(4, results.Count(x => x.ContentTypeId == 1));
|
||||
Assert.AreEqual(2, results.Count(x => x.ContentTypeId == 2));
|
||||
Assert.False(results.Any(x => x.VersionId == 9)); // Most recent for content type 2
|
||||
Assert.False(results.Any(x => x.VersionId == 3)); // Most recent for content type 1 today
|
||||
Assert.False(results.Any(x => x.VersionId == 6)); // Most recent for content type 1 yesterday
|
||||
});
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void Apply_HasOverridePolicy_RespectsPreventCleanup(
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
[Frozen] Mock<IOptions<ContentSettings>> contentSettings,
|
||||
DefaultContentVersionCleanupPolicy sut)
|
||||
{
|
||||
var historicItems = new List<ContentVersionMeta>
|
||||
{
|
||||
new ContentVersionMeta(versionId: 1, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 2, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 3, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
// another content & type
|
||||
new ContentVersionMeta(versionId: 4, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 5, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 6, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
};
|
||||
|
||||
contentSettings.Setup(x => x.Value).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new Cms.Core.Configuration.Models.ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 0,
|
||||
KeepLatestVersionPerDayForDays = 0
|
||||
}
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetCleanupPolicies())
|
||||
.Returns(new ContentVersionCleanupPolicySettings[]
|
||||
{
|
||||
new ContentVersionCleanupPolicySettings{ ContentTypeId = 2, PreventCleanup = true }
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(historicItems);
|
||||
|
||||
var results = sut.Apply(DateTime.Today, historicItems).ToList();
|
||||
|
||||
Assert.True(results.All(x => x.ContentTypeId == 1));
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void Apply_HasOverridePolicy_RespectsKeepAll(
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
[Frozen] Mock<IOptions<ContentSettings>> contentSettings,
|
||||
DefaultContentVersionCleanupPolicy sut)
|
||||
{
|
||||
var historicItems = new List<ContentVersionMeta>
|
||||
{
|
||||
new ContentVersionMeta(versionId: 1, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 2, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 3, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
// another content & type
|
||||
new ContentVersionMeta(versionId: 4, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 5, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 6, contentId: 2, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
};
|
||||
|
||||
contentSettings.Setup(x => x.Value).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new Cms.Core.Configuration.Models.ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 0,
|
||||
KeepLatestVersionPerDayForDays = 0
|
||||
}
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetCleanupPolicies())
|
||||
.Returns(new ContentVersionCleanupPolicySettings[]
|
||||
{
|
||||
new ContentVersionCleanupPolicySettings{ ContentTypeId = 2, PreventCleanup = false, KeepAllVersionsNewerThanDays = 3 }
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(historicItems);
|
||||
|
||||
var results = sut.Apply(DateTime.Today, historicItems).ToList();
|
||||
|
||||
Assert.True(results.All(x => x.ContentTypeId == 1));
|
||||
}
|
||||
|
||||
[Test, AutoMoqData]
|
||||
public void Apply_HasOverridePolicy_RespectsKeepLatest(
|
||||
[Frozen] Mock<IDocumentVersionRepository> documentVersionRepository,
|
||||
[Frozen] Mock<IOptions<ContentSettings>> contentSettings,
|
||||
DefaultContentVersionCleanupPolicy sut)
|
||||
{
|
||||
var historicItems = new List<ContentVersionMeta>
|
||||
{
|
||||
new ContentVersionMeta(versionId: 1, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 2, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 3, contentId: 1, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
// another content
|
||||
new ContentVersionMeta(versionId: 4, contentId: 2, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 5, contentId: 2, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 6, contentId: 2, contentTypeId: 1, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
// another content & type
|
||||
new ContentVersionMeta(versionId: 7, contentId: 3, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-3), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 8, contentId: 3, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-2), false, false, false, null),
|
||||
new ContentVersionMeta(versionId: 9, contentId: 3, contentTypeId: 2, -1, versionDate: DateTime.Today.AddHours(-1), false, false, false, null),
|
||||
};
|
||||
|
||||
contentSettings.Setup(x => x.Value).Returns(new ContentSettings()
|
||||
{
|
||||
ContentVersionCleanupPolicy = new Cms.Core.Configuration.Models.ContentVersionCleanupPolicySettings()
|
||||
{
|
||||
EnableCleanup = true,
|
||||
KeepAllVersionsNewerThanDays = 0,
|
||||
KeepLatestVersionPerDayForDays = 0
|
||||
}
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetCleanupPolicies())
|
||||
.Returns(new ContentVersionCleanupPolicySettings[]
|
||||
{
|
||||
new ContentVersionCleanupPolicySettings{ ContentTypeId = 2, PreventCleanup = false, KeepLatestVersionPerDayForDays = 3 }
|
||||
});
|
||||
|
||||
documentVersionRepository.Setup(x => x.GetDocumentVersionsEligibleForCleanup())
|
||||
.Returns(historicItems);
|
||||
|
||||
var results = sut.Apply(DateTime.Today, historicItems).ToList();
|
||||
|
||||
// By default no historic versions are kept
|
||||
// Override policy for content type 2 keeps latest per day for 3 days, no versions retained for content type with id 1
|
||||
// There were 3 entries for content type 2 all on the same day
|
||||
// version id 9 is most recent for content type 2, and should be filtered, all the rest should be present.
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.AreEqual(8, results.Count);
|
||||
Assert.AreEqual(2, results.Count(x => x.ContentTypeId == 2));
|
||||
Assert.False(results.Any(x => x.VersionId == 9));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,14 @@ using Umbraco.Cms.Core.IO;
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
{
|
||||
[TestFixture]
|
||||
public class ViewHelperTests
|
||||
public class DefaultViewContentProviderTests
|
||||
{
|
||||
private IDefaultViewContentProvider DefaultViewContentProvider => new DefaultViewContentProvider();
|
||||
|
||||
[Test]
|
||||
public void NoOptions()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent();
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent();
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
|
||||
@@ -24,7 +26,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
[Test]
|
||||
public void Layout()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent(layoutPageAlias: "Dharznoik");
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent(layoutPageAlias: "Dharznoik");
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
|
||||
@@ -36,7 +38,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
[Test]
|
||||
public void ClassName()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent(modelClassName: "ClassName");
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent(modelClassName: "ClassName");
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ClassName>
|
||||
@@ -48,7 +50,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
[Test]
|
||||
public void Namespace()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent(modelNamespace: "Models");
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent(modelNamespace: "Models");
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
|
||||
@@ -60,7 +62,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
[Test]
|
||||
public void ClassNameAndNamespace()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models");
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models");
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.ClassName>
|
||||
@@ -73,7 +75,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
[Test]
|
||||
public void ClassNameAndNamespaceAndAlias()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels");
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent(modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels");
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<MyModels.ClassName>
|
||||
@@ -86,7 +88,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Templates
|
||||
[Test]
|
||||
public void Combined()
|
||||
{
|
||||
var view = ViewHelper.GetDefaultFileContent(layoutPageAlias: "Dharznoik", modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels");
|
||||
var view = DefaultViewContentProvider.GetDefaultFileContent(layoutPageAlias: "Dharznoik", modelClassName: "ClassName", modelNamespace: "My.Models", modelNamespaceAlias: "MyModels");
|
||||
Assert.AreEqual(
|
||||
FixView(@"@using Umbraco.Cms.Web.Common.PublishedModels;
|
||||
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<MyModels.ClassName>
|
||||
@@ -66,7 +66,8 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Logging
|
||||
|
||||
ILogger<SerilogJsonLogViewer> logger = Mock.Of<ILogger<SerilogJsonLogViewer>>();
|
||||
var logViewerConfig = new LogViewerConfig(LogViewerQueryRepository, Mock.Of<IScopeProvider>());
|
||||
_logViewer = new SerilogJsonLogViewer(logger, logViewerConfig, loggingConfiguration, Log.Logger);
|
||||
var logLevelLoader = Mock.Of<ILogLevelLoader>();
|
||||
_logViewer = new SerilogJsonLogViewer(logger, logViewerConfig, loggingConfiguration, logLevelLoader, Log.Logger);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Moq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.PublishedCache.NuCache.DataSource;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContentSerializationTests
|
||||
@@ -77,9 +77,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
public override int Compare(CultureVariation x, CultureVariation y)
|
||||
{
|
||||
if (x == null && y == null) return 0;
|
||||
if (x == null && y != null) return -1;
|
||||
if (x != null && y == null) return 1;
|
||||
if (x == null && y == null)
|
||||
return 0;
|
||||
if (x == null && y != null)
|
||||
return -1;
|
||||
if (x != null && y == null)
|
||||
return 1;
|
||||
|
||||
return x.Date.CompareTo(y.Date) | x.IsDraft.CompareTo(y.IsDraft) | x.Name.CompareTo(y.Name) | x.UrlSegment.CompareTo(y.UrlSegment);
|
||||
}
|
||||
@@ -89,9 +92,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
public override int Compare(PropertyData x, PropertyData y)
|
||||
{
|
||||
if (x == null && y == null) return 0;
|
||||
if (x == null && y != null) return -1;
|
||||
if (x != null && y == null) return 1;
|
||||
if (x == null && y == null)
|
||||
return 0;
|
||||
if (x == null && y != null)
|
||||
return -1;
|
||||
if (x != null && y == null)
|
||||
return 1;
|
||||
|
||||
var xVal = x.Value?.ToString() ?? string.Empty;
|
||||
var yVal = y.Value?.ToString() ?? string.Empty;
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishContentCacheTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private IPublishedContentCache _cache;
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.PublishContentCacheTestsXml();
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
// configure the Home content type to be composed of another for tests.
|
||||
var compositionType = new ContentType(TestHelper.ShortStringHelper, -1)
|
||||
{
|
||||
Alias = "MyCompositionAlias"
|
||||
};
|
||||
contentTypes.First(x => x.Alias == "Home").AddContentType(compositionType);
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
|
||||
_cache = GetPublishedSnapshot().Content;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Has_Content()
|
||||
{
|
||||
Assert.IsTrue(_cache.HasContent());
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Get_Root_Docs()
|
||||
{
|
||||
var result = _cache.GetAtRoot();
|
||||
Assert.AreEqual(2, result.Count());
|
||||
Assert.AreEqual(1046, result.ElementAt(0).Id);
|
||||
Assert.AreEqual(1172, result.ElementAt(1).Id);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("/", 1046)]
|
||||
[TestCase("/home", 1046)]
|
||||
[TestCase("/Home", 1046)] //test different cases
|
||||
[TestCase("/home/sub1", 1173)]
|
||||
[TestCase("/Home/sub1", 1173)]
|
||||
[TestCase("/home/Sub1", 1173)] //test different cases
|
||||
[TestCase("/home/Sub'Apostrophe", 1177)]
|
||||
public void Get_Node_By_Route(string route, int nodeId)
|
||||
{
|
||||
var result = _cache.GetByRoute(route, false);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(nodeId, result.Id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[TestCase("/", 1046)]
|
||||
[TestCase("/sub1", 1173)]
|
||||
[TestCase("/Sub1", 1173)]
|
||||
public void Get_Node_By_Route_Hiding_Top_Level_Nodes(string route, int nodeId)
|
||||
{
|
||||
var result = _cache.GetByRoute(route, true);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(nodeId, result.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Unit tests for IPublishedContent and extensions
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class PublishedContentDataTableTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private readonly DataType[] _dataTypes = GetDefaultDataTypes();
|
||||
|
||||
private static ContentType CreateContentType(string name, IDataType dataType, IReadOnlyDictionary<string, string> propertyAliasesAndNames)
|
||||
{
|
||||
var contentType = new ContentType(TestHelper.ShortStringHelper, -1)
|
||||
{
|
||||
Alias = name,
|
||||
Name = name,
|
||||
Key = Guid.NewGuid(),
|
||||
Id = name.GetHashCode()
|
||||
};
|
||||
foreach(var prop in propertyAliasesAndNames)
|
||||
{
|
||||
contentType.AddPropertyType(new PropertyType(TestHelper.ShortStringHelper, dataType, prop.Key)
|
||||
{
|
||||
Name = prop.Value
|
||||
});
|
||||
}
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private IEnumerable<ContentNodeKit> CreateCache(
|
||||
bool createChildren,
|
||||
IDataType dataType,
|
||||
out ContentType[] contentTypes)
|
||||
{
|
||||
var result = new List<ContentNodeKit>();
|
||||
var valueCounter = 1;
|
||||
var parentId = 3;
|
||||
|
||||
var properties = new Dictionary<string, string>
|
||||
{
|
||||
["property1"] = "Property 1",
|
||||
["property2"] = "Property 2",
|
||||
};
|
||||
|
||||
ContentType parentContentType = CreateContentType("Parent", dataType, new Dictionary<string, string>(properties)
|
||||
{
|
||||
["property3"] = "Property 3"
|
||||
});
|
||||
ContentType childContentType = CreateContentType("Child", dataType, new Dictionary<string, string>(properties)
|
||||
{
|
||||
["property4"] = "Property 4"
|
||||
});
|
||||
ContentType child2ContentType = CreateContentType("Child2", dataType, new Dictionary<string, string>(properties)
|
||||
{
|
||||
["property4"] = "Property 4"
|
||||
});
|
||||
|
||||
contentTypes = new[] { parentContentType, childContentType, child2ContentType };
|
||||
|
||||
ContentData parentData = new ContentDataBuilder()
|
||||
.WithName("Page" + Guid.NewGuid())
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("property1", "value" + valueCounter)
|
||||
.WithPropertyData("property2", "value" + (valueCounter + 1))
|
||||
.WithPropertyData("property3", "value" + (valueCounter + 2))
|
||||
.Build())
|
||||
.Build();
|
||||
|
||||
ContentNodeKit parent = ContentNodeKitBuilder.CreateWithContent(
|
||||
parentContentType.Id,
|
||||
parentId, $"-1,{parentId}",
|
||||
draftData: parentData,
|
||||
publishedData: parentData);
|
||||
|
||||
result.Add(parent);
|
||||
|
||||
if (createChildren)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
valueCounter += 3;
|
||||
var childId = parentId + i + 1;
|
||||
|
||||
ContentData childData = new ContentDataBuilder()
|
||||
.WithName("Page" + Guid.NewGuid())
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("property1", "value" + valueCounter)
|
||||
.WithPropertyData("property2", "value" + (valueCounter + 1))
|
||||
.WithPropertyData("property4", "value" + (valueCounter + 2))
|
||||
.Build())
|
||||
.Build();
|
||||
|
||||
ContentNodeKit child = ContentNodeKitBuilder.CreateWithContent(
|
||||
i > 0 ? childContentType.Id : child2ContentType.Id,
|
||||
childId, $"-1,{parentId},{childId}", i,
|
||||
draftData: childData,
|
||||
publishedData: childData);
|
||||
|
||||
result.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void To_DataTable()
|
||||
{
|
||||
var cache = CreateCache(true, _dataTypes[0], out ContentType[] contentTypes);
|
||||
InitializedCache(cache, contentTypes, dataTypes: _dataTypes);
|
||||
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var root = snapshot.Content.GetAtRoot().First();
|
||||
|
||||
var dt = root.ChildrenAsTable(
|
||||
VariationContextAccessor,
|
||||
ContentTypeService,
|
||||
MediaTypeService,
|
||||
Mock.Of<IMemberTypeService>(),
|
||||
Mock.Of<IPublishedUrlProvider>());
|
||||
|
||||
Assert.AreEqual(11, dt.Columns.Count);
|
||||
Assert.AreEqual(3, dt.Rows.Count);
|
||||
Assert.AreEqual("value4", dt.Rows[0]["Property 1"]);
|
||||
Assert.AreEqual("value5", dt.Rows[0]["Property 2"]);
|
||||
Assert.AreEqual("value6", dt.Rows[0]["Property 4"]);
|
||||
Assert.AreEqual("value7", dt.Rows[1]["Property 1"]);
|
||||
Assert.AreEqual("value8", dt.Rows[1]["Property 2"]);
|
||||
Assert.AreEqual("value9", dt.Rows[1]["Property 4"]);
|
||||
Assert.AreEqual("value10", dt.Rows[2]["Property 1"]);
|
||||
Assert.AreEqual("value11", dt.Rows[2]["Property 2"]);
|
||||
Assert.AreEqual("value12", dt.Rows[2]["Property 4"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void To_DataTable_With_Filter()
|
||||
{
|
||||
var cache = CreateCache(true, _dataTypes[0], out ContentType[] contentTypes);
|
||||
InitializedCache(cache, contentTypes, dataTypes: _dataTypes);
|
||||
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var root = snapshot.Content.GetAtRoot().First();
|
||||
|
||||
var dt = root.ChildrenAsTable(
|
||||
VariationContextAccessor,
|
||||
ContentTypeService,
|
||||
MediaTypeService,
|
||||
Mock.Of<IMemberTypeService>(),
|
||||
Mock.Of<IPublishedUrlProvider>(),
|
||||
"Child");
|
||||
|
||||
Assert.AreEqual(11, dt.Columns.Count);
|
||||
Assert.AreEqual(2, dt.Rows.Count);
|
||||
Assert.AreEqual("value7", dt.Rows[0]["Property 1"]);
|
||||
Assert.AreEqual("value8", dt.Rows[0]["Property 2"]);
|
||||
Assert.AreEqual("value9", dt.Rows[0]["Property 4"]);
|
||||
Assert.AreEqual("value10", dt.Rows[1]["Property 1"]);
|
||||
Assert.AreEqual("value11", dt.Rows[1]["Property 2"]);
|
||||
Assert.AreEqual("value12", dt.Rows[1]["Property 4"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void To_DataTable_No_Rows()
|
||||
{
|
||||
var cache = CreateCache(false, _dataTypes[0], out ContentType[] contentTypes);
|
||||
InitializedCache(cache, contentTypes, dataTypes: _dataTypes);
|
||||
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var root = snapshot.Content.GetAtRoot().First();
|
||||
|
||||
var dt = root.ChildrenAsTable(
|
||||
VariationContextAccessor,
|
||||
ContentTypeService,
|
||||
MediaTypeService,
|
||||
Mock.Of<IMemberTypeService>(),
|
||||
Mock.Of<IPublishedUrlProvider>());
|
||||
|
||||
//will return an empty data table
|
||||
Assert.AreEqual(0, dt.Columns.Count);
|
||||
Assert.AreEqual(0, dt.Rows.Count);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedContentExtensionTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private const string XmlContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT inherited ANY>
|
||||
<!ATTLIST inherited id ID #REQUIRED>
|
||||
]>
|
||||
<root id=""-1"">
|
||||
<inherited id=""1100"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""1"" sortOrder=""1"" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" nodeName=""Home"" urlName=""home"" writerName=""admin"" creatorName=""admin"" path=""-1,1046"" isDoc=""""/>
|
||||
</root>";
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
XmlContent,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
// configure inheritance for content types
|
||||
var baseType = new ContentType(TestHelper.ShortStringHelper, -1) { Alias = "Base" };
|
||||
contentTypes[0].AddContentType(baseType);
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDocumentType_NonRecursive_ActualType_ReturnsTrue()
|
||||
{
|
||||
var publishedContent = GetContent(1100);
|
||||
Assert.That(publishedContent.IsDocumentType("Inherited", false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDocumentType_NonRecursive_BaseType_ReturnsFalse()
|
||||
{
|
||||
var publishedContent = GetContent(1100);
|
||||
Assert.That(publishedContent.IsDocumentType("Base", false), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDocumentType_Recursive_ActualType_ReturnsTrue()
|
||||
{
|
||||
var publishedContent = GetContent(1100);
|
||||
Assert.That(publishedContent.IsDocumentType("Inherited", true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDocumentType_Recursive_BaseType_ReturnsTrue()
|
||||
{
|
||||
var publishedContent = GetContent(1100);
|
||||
Assert.That(publishedContent.IsDocumentType("Base", true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsDocumentType_Recursive_InvalidBaseType_ReturnsFalse()
|
||||
{
|
||||
var publishedContent = GetContent(1100);
|
||||
Assert.That(publishedContent.IsDocumentType("invalidbase", true), Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedContentLanguageVariantTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
var dataTypes = GetDefaultDataTypes();
|
||||
var cache = CreateCache(dataTypes, out ContentType[] contentTypes);
|
||||
|
||||
InitializedCache(cache, contentTypes, dataTypes: dataTypes);
|
||||
}
|
||||
|
||||
protected override PropertyValueConverterCollection PropertyValueConverterCollection
|
||||
{
|
||||
get
|
||||
{
|
||||
PropertyValueConverterCollection collection = base.PropertyValueConverterCollection;
|
||||
return new PropertyValueConverterCollection(() => collection.Append(new TestNoValueValueConverter()));
|
||||
}
|
||||
}
|
||||
|
||||
private class TestNoValueValueConverter : SimpleTinyMceValueConverter
|
||||
{
|
||||
public override bool IsConverter(IPublishedPropertyType propertyType)
|
||||
=> propertyType.Alias == "noprop";
|
||||
|
||||
// for this test, we return false for IsValue for this property
|
||||
public override bool? IsValue(object value, PropertyValueLevel level) => false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to mock localization service
|
||||
/// </summary>
|
||||
/// <param name="contentTypes"></param>
|
||||
/// <param name="dataTypes"></param>
|
||||
/// <returns></returns>
|
||||
protected override ServiceContext CreateServiceContext(IContentType[] contentTypes, IMediaType[] mediaTypes, IDataType[] dataTypes)
|
||||
{
|
||||
var serviceContext = base.CreateServiceContext(contentTypes, mediaTypes, dataTypes);
|
||||
|
||||
var localizationService = Mock.Get(serviceContext.LocalizationService);
|
||||
|
||||
var languages = new List<Language>
|
||||
{
|
||||
new Language(GlobalSettings, "en-US") { Id = 1, CultureName = "English", IsDefault = true },
|
||||
new Language(GlobalSettings, "fr") { Id = 2, CultureName = "French" },
|
||||
new Language(GlobalSettings, "es") { Id = 3, CultureName = "Spanish", FallbackLanguageId = 1 },
|
||||
new Language(GlobalSettings, "it") { Id = 4, CultureName = "Italian", FallbackLanguageId = 3 },
|
||||
new Language(GlobalSettings, "de") { Id = 5, CultureName = "German" },
|
||||
new Language(GlobalSettings, "da") { Id = 6, CultureName = "Danish", FallbackLanguageId = 8 },
|
||||
new Language(GlobalSettings, "sv") { Id = 7, CultureName = "Swedish", FallbackLanguageId = 6 },
|
||||
new Language(GlobalSettings, "no") { Id = 8, CultureName = "Norweigan", FallbackLanguageId = 7 },
|
||||
new Language(GlobalSettings, "nl") { Id = 9, CultureName = "Dutch", FallbackLanguageId = 1 }
|
||||
};
|
||||
|
||||
localizationService.Setup(x => x.GetAllLanguages()).Returns(languages);
|
||||
localizationService.Setup(x => x.GetLanguageById(It.IsAny<int>()))
|
||||
.Returns((int id) => languages.SingleOrDefault(y => y.Id == id));
|
||||
localizationService.Setup(x => x.GetLanguageByIsoCode(It.IsAny<string>()))
|
||||
.Returns((string c) => languages.SingleOrDefault(y => y.IsoCode == c));
|
||||
|
||||
return serviceContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a content cache
|
||||
/// </summary>
|
||||
/// <param name="dataTypes"></param>
|
||||
/// <param name="contentTypes"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Builds a content hierarchy of 3 nodes, each has a different set of cultural properties.
|
||||
/// The first 2 share the same content type, the last one is a different content type.
|
||||
/// NOTE: The content items themselves are 'Invariant' but their properties are 'Variant' by culture.
|
||||
/// Normally in Umbraco this is prohibited but our APIs and database do actually support that behavior.
|
||||
/// It is simpler to have these tests run this way, else we would need to use WithCultureInfos
|
||||
/// for each item and pass in name values for all cultures we are supporting and then specify the
|
||||
/// default VariationContextAccessor.VariationContext value to be a default culture instead of "".
|
||||
/// </remarks>
|
||||
private IEnumerable<ContentNodeKit> CreateCache(IDataType[] dataTypes, out ContentType[] contentTypes)
|
||||
{
|
||||
var result = new List<ContentNodeKit>();
|
||||
|
||||
var propertyDataTypes = new Dictionary<string, IDataType>
|
||||
{
|
||||
// we only have one data type for this test which will be resolved with string empty.
|
||||
[string.Empty] = dataTypes[0]
|
||||
};
|
||||
|
||||
var contentType1 = new ContentType(ShortStringHelper, -1);
|
||||
|
||||
ContentData item1Data = new ContentDataBuilder()
|
||||
.WithName("Content 1")
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("welcomeText", "Welcome")
|
||||
.WithPropertyData("welcomeText", "Welcome", "en-US")
|
||||
.WithPropertyData("welcomeText", "Willkommen", "de")
|
||||
.WithPropertyData("welcomeText", "Welkom", "nl")
|
||||
.WithPropertyData("welcomeText2", "Welcome")
|
||||
.WithPropertyData("welcomeText2", "Welcome", "en-US")
|
||||
.WithPropertyData("noprop", "xxx")
|
||||
.Build())
|
||||
// build with a dynamically created content type
|
||||
.Build(ShortStringHelper, propertyDataTypes, contentType1, "ContentType1");
|
||||
|
||||
ContentNodeKit item1 = ContentNodeKitBuilder.CreateWithContent(
|
||||
contentType1.Id,
|
||||
1, "-1,1",
|
||||
draftData: item1Data,
|
||||
publishedData: item1Data);
|
||||
|
||||
result.Add(item1);
|
||||
|
||||
ContentData item2Data = new ContentDataBuilder()
|
||||
.WithName("Content 2")
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("welcomeText", "Welcome")
|
||||
.WithPropertyData("welcomeText", "Welcome", "en-US")
|
||||
.WithPropertyData("noprop", "xxx")
|
||||
.Build())
|
||||
// build while dynamically updating the same content type
|
||||
.Build(ShortStringHelper, propertyDataTypes, contentType1);
|
||||
|
||||
ContentNodeKit item2 = ContentNodeKitBuilder.CreateWithContent(
|
||||
contentType1.Id,
|
||||
2, "-1,1,2",
|
||||
parentContentId: 1,
|
||||
draftData: item2Data,
|
||||
publishedData: item2Data);
|
||||
|
||||
result.Add(item2);
|
||||
|
||||
var contentType2 = new ContentType(ShortStringHelper, -1);
|
||||
|
||||
ContentData item3Data = new ContentDataBuilder()
|
||||
.WithName("Content 3")
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("prop3", "Oxxo")
|
||||
.WithPropertyData("prop3", "Oxxo", "en-US")
|
||||
.Build())
|
||||
// build with a dynamically created content type
|
||||
.Build(ShortStringHelper, propertyDataTypes, contentType2, "ContentType2");
|
||||
|
||||
ContentNodeKit item3 = ContentNodeKitBuilder.CreateWithContent(
|
||||
contentType2.Id,
|
||||
3, "-1,1,2,3",
|
||||
parentContentId: 2,
|
||||
draftData: item3Data,
|
||||
publishedData: item3Data);
|
||||
|
||||
result.Add(item3);
|
||||
|
||||
contentTypes = new[] { contentType1, contentType2 };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Populated_Requested_Language()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText", "en-US");
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Populated_Requested_Non_Default_Language()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText", "de");
|
||||
Assert.AreEqual("Willkommen", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_For_Unpopulated_Requested_Language_Without_Fallback()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText", "fr");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_For_Unpopulated_Requested_Language_With_Fallback_Unless_Requested()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText", "es");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Unpopulated_Requested_Language_With_Fallback()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText", "es", fallback: Fallback.ToLanguage);
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Unpopulated_Requested_Language_With_Fallback_Over_Two_Levels()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText", "it", fallback: Fallback.To(Fallback.Language, Fallback.Ancestors));
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Do_Not_GetContent_For_Unpopulated_Requested_Language_With_Fallback_Over_That_Loops()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First();
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText", "no", fallback: Fallback.ToLanguage);
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_Recursively_Unless_Requested()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First();
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText2");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_Recursively()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First();
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText2", fallback: Fallback.ToAncestors);
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_Recursively_Unless_Requested2()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First().Children.First();
|
||||
Assert.IsNull(content.GetProperty("welcomeText2"));
|
||||
var value = content.Value(Mock.Of<IPublishedValueFallback>(), "welcomeText2");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_Recursively2()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First().Children.First();
|
||||
Assert.IsNull(content.GetProperty("welcomeText2"));
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText2", fallback: Fallback.ToAncestors);
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_Recursively3()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First().Children.First();
|
||||
Assert.IsNull(content.GetProperty("noprop"));
|
||||
var value = content.Value(PublishedValueFallback, "noprop", fallback: Fallback.ToAncestors);
|
||||
// property has no value - based on the converter
|
||||
// but we still get the value (ie, the converter would do something)
|
||||
Assert.AreEqual("xxx", value.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_With_Recursive_Priority()
|
||||
{
|
||||
VariationContextAccessor.VariationContext = new VariationContext("nl");
|
||||
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First();
|
||||
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText", "nl", fallback: Fallback.To(Fallback.Ancestors, Fallback.Language));
|
||||
|
||||
// No Dutch value is directly assigned. Check has fallen back to Dutch value from parent.
|
||||
Assert.AreEqual("Welkom", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Content_With_Fallback_Language_Priority()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First();
|
||||
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText", "nl", fallback: Fallback.ToLanguage);
|
||||
|
||||
// No Dutch value is directly assigned. Check has fallen back to English value from language variant.
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Throws_For_Non_Supported_Fallback()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First();
|
||||
|
||||
Assert.Throws<NotSupportedException>(() => content.Value(PublishedValueFallback, "welcomeText", "nl", fallback: Fallback.To(999)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Fallback_To_Default_Value()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var content = snapshot.Content.GetAtRoot().First().Children.First();
|
||||
|
||||
// no Dutch value is assigned, so getting null
|
||||
var value = content.Value(PublishedValueFallback, "welcomeText", "nl");
|
||||
Assert.IsNull(value);
|
||||
|
||||
// even if we 'just' provide a default value
|
||||
value = content.Value(PublishedValueFallback, "welcomeText", "nl", defaultValue: "woop");
|
||||
Assert.IsNull(value);
|
||||
|
||||
// but it works with proper fallback settings
|
||||
value = content.Value(PublishedValueFallback, "welcomeText", "nl", fallback: Fallback.ToDefaultValue, defaultValue: "woop");
|
||||
Assert.AreEqual("woop", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,193 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.Hosting;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Logging;
|
||||
using Umbraco.Cms.Core.Media;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Core.Templates;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests the methods on IPublishedContent using the DefaultPublishedContentStore
|
||||
/// </summary>
|
||||
|
||||
[TestFixture]
|
||||
[UmbracoTest(TypeLoader = UmbracoTestOptions.TypeLoader.PerFixture)]
|
||||
public class PublishedContentTests : PublishedContentTestBase
|
||||
public class PublishedContentTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
protected override void Compose()
|
||||
{
|
||||
base.Compose();
|
||||
_publishedSnapshotAccessorMock = new Mock<IPublishedSnapshotAccessor>();
|
||||
Builder.Services.AddUnique<IPublishedSnapshotAccessor>(_publishedSnapshotAccessorMock.Object);
|
||||
|
||||
Builder.Services.AddUnique<IPublishedModelFactory>(f => new PublishedModelFactory(f.GetRequiredService<TypeLoader>().GetTypes<PublishedContentModel>(), f.GetRequiredService<IPublishedValueFallback>()));
|
||||
Builder.Services.AddUnique<IPublishedContentTypeFactory, PublishedContentTypeFactory>();
|
||||
Builder.Services.AddUnique<IPublishedValueFallback, PublishedValueFallback>();
|
||||
|
||||
var loggerFactory = NullLoggerFactory.Instance;
|
||||
var mediaService = Mock.Of<IMediaService>();
|
||||
var contentTypeBaseServiceProvider = Mock.Of<IContentTypeBaseServiceProvider>();
|
||||
var umbracoContextAccessor = Mock.Of<IUmbracoContextAccessor>();
|
||||
var backOfficeSecurityAccessor = Mock.Of<IBackOfficeSecurityAccessor>();
|
||||
var publishedUrlProvider = Mock.Of<IPublishedUrlProvider>();
|
||||
var imageSourceParser = new HtmlImageSourceParser(publishedUrlProvider);
|
||||
var serializer = new ConfigurationEditorJsonSerializer();
|
||||
var mediaFileService = new MediaFileManager(Mock.Of<IFileSystem>(), Mock.Of<IMediaPathScheme>(),
|
||||
loggerFactory.CreateLogger<MediaFileManager>(), Mock.Of<IShortStringHelper>());
|
||||
var pastedImages = new RichTextEditorPastedImages(umbracoContextAccessor, loggerFactory.CreateLogger<RichTextEditorPastedImages>(), HostingEnvironment, mediaService, contentTypeBaseServiceProvider, mediaFileService, ShortStringHelper, publishedUrlProvider, serializer);
|
||||
var linkParser = new HtmlLocalLinkParser(umbracoContextAccessor, publishedUrlProvider);
|
||||
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(
|
||||
new DataType(new VoidEditor(DataValueEditorFactory), serializer) { Id = 1 },
|
||||
new DataType(new TrueFalsePropertyEditor(DataValueEditorFactory, IOHelper), serializer) { Id = 1001 },
|
||||
new DataType(new RichTextPropertyEditor(DataValueEditorFactory, backOfficeSecurityAccessor, imageSourceParser, linkParser, pastedImages, IOHelper, Mock.Of<IImageUrlGenerator>()), serializer) { Id = 1002 },
|
||||
new DataType(new IntegerPropertyEditor(DataValueEditorFactory), serializer) { Id = 1003 },
|
||||
new DataType(new TextboxPropertyEditor(DataValueEditorFactory, IOHelper), serializer) { Id = 1004 },
|
||||
new DataType(new MediaPickerPropertyEditor(DataValueEditorFactory, IOHelper), serializer) { Id = 1005 });
|
||||
Builder.Services.AddUnique<IDataTypeService>(f => dataTypeService);
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
var factory = Factory.GetRequiredService<IPublishedContentTypeFactory>() as PublishedContentTypeFactory;
|
||||
|
||||
// need to specify a custom callback for unit tests
|
||||
// AutoPublishedContentTypes generates properties automatically
|
||||
// when they are requested, but we must declare those that we
|
||||
// explicitely want to be here...
|
||||
|
||||
IEnumerable<IPublishedPropertyType> CreatePropertyTypes(IPublishedContentType contentType)
|
||||
{
|
||||
// AutoPublishedContentType will auto-generate other properties
|
||||
yield return factory.CreatePropertyType(contentType, "umbracoNaviHide", 1001);
|
||||
yield return factory.CreatePropertyType(contentType, "selectedNodes", 1);
|
||||
yield return factory.CreatePropertyType(contentType, "umbracoUrlAlias", 1);
|
||||
yield return factory.CreatePropertyType(contentType, "content", 1002);
|
||||
yield return factory.CreatePropertyType(contentType, "testRecursive", 1);
|
||||
}
|
||||
|
||||
var compositionAliases = new[] { "MyCompositionAlias" };
|
||||
var anythingType = new AutoPublishedContentType(Guid.NewGuid(), 0, "anything", compositionAliases, CreatePropertyTypes);
|
||||
var homeType = new AutoPublishedContentType(Guid.NewGuid(), 0, "home", compositionAliases, CreatePropertyTypes);
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = alias => alias.InvariantEquals("home") ? homeType : anythingType;
|
||||
}
|
||||
|
||||
|
||||
protected override TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, ILogger<TypeLoader> logger, IProfilingLogger profilingLogger , IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
var baseLoader = base.CreateTypeLoader(ioHelper, typeFinder, runtimeCache, logger, profilingLogger , hostingEnvironment);
|
||||
|
||||
return new TypeLoader(typeFinder, runtimeCache, new DirectoryInfo(hostingEnvironment.LocalTempPath), logger, profilingLogger , false,
|
||||
// this is so the model factory looks into the test assembly
|
||||
baseLoader.AssembliesToScan
|
||||
.Union(new[] { typeof(PublishedContentTests).Assembly })
|
||||
.ToList());
|
||||
}
|
||||
|
||||
private readonly Guid _node1173Guid = Guid.NewGuid();
|
||||
private Mock<IPublishedSnapshotAccessor> _publishedSnapshotAccessorMock;
|
||||
private PublishedModelFactory _publishedModelFactory;
|
||||
private DataType[] _dataTypes;
|
||||
|
||||
protected override string GetXmlContent(int templateId)
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
return @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<!DOCTYPE root[
|
||||
<!ELEMENT Home ANY>
|
||||
<!ATTLIST Home id ID #REQUIRED>
|
||||
<!ELEMENT CustomDocument ANY>
|
||||
<!ATTLIST CustomDocument id ID #REQUIRED>
|
||||
]>
|
||||
<root id=""-1"">
|
||||
<Home id=""1046"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-06-12T14:13:17"" updateDate=""2012-07-20T18:50:43"" nodeName=""Home"" urlName=""home"" writerName=""admin"" creatorName=""admin"" path=""-1,1046"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[this/is/my/alias, anotheralias]]></umbracoUrlAlias>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
<testRecursive><![CDATA[This is the recursive val]]></testRecursive>
|
||||
<Home id=""1173"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:06:45"" updateDate=""2012-07-20T19:07:31"" nodeName=""Sub1"" urlName=""sub1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173"" isDoc="""" key=""" + _node1173Guid + @""">
|
||||
<content><![CDATA[<div>This is some content</div>]]></content>
|
||||
<umbracoUrlAlias><![CDATA[page2/alias, 2ndpagealias]]></umbracoUrlAlias>
|
||||
<testRecursive><![CDATA[]]></testRecursive>
|
||||
<Home id=""1174"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-20T18:07:54"" updateDate=""2012-07-20T19:10:27"" nodeName=""Sub2"" urlName=""sub2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1174"" isDoc="""">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoUrlAlias><![CDATA[only/one/alias]]></umbracoUrlAlias>
|
||||
<creatorName><![CDATA[Custom data with same property name as the member name]]></creatorName>
|
||||
<testRecursive><![CDATA[]]></testRecursive>
|
||||
</Home>
|
||||
<CustomDocument id=""117"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2018-07-18T10:06:37"" updateDate=""2018-07-18T10:06:37"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,117"" isDoc="""" />
|
||||
<CustomDocument id=""1177"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub 1"" urlName=""custom-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1177"" isDoc="""" />
|
||||
<CustomDocument id=""1178"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""4"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-16T14:23:35"" nodeName=""custom sub 2"" urlName=""custom-sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178"" isDoc="""">
|
||||
<CustomDocument id=""1179"" parentID=""1178"" level=""4"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""1"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""custom sub sub 1"" urlName=""custom-sub-sub-1"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1178,1179"" isDoc="""" />
|
||||
</CustomDocument>
|
||||
<Home id=""1176"" parentID=""1173"" level=""3"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""5"" createDate=""2012-07-20T18:08:08"" updateDate=""2012-07-20T19:10:52"" nodeName=""Sub 3"" urlName=""sub-3"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1173,1176"" isDoc="""" key=""CDB83BBC-A83B-4BA6-93B8-AADEF67D3C09"">
|
||||
<content><![CDATA[]]></content>
|
||||
<umbracoNaviHide>1</umbracoNaviHide>
|
||||
</Home>
|
||||
</Home>
|
||||
<Home id=""1175"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1044"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-20T18:08:01"" updateDate=""2012-07-20T18:49:32"" nodeName=""Sub 2"" urlName=""sub-2"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,1175"" isDoc=""""><content><![CDATA[]]></content>
|
||||
</Home>
|
||||
<CustomDocument id=""4444"" parentID=""1046"" level=""2"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""3"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1046,4444"" isDoc="""">
|
||||
<selectedNodes><![CDATA[1172,1176,1173]]></selectedNodes>
|
||||
</CustomDocument>
|
||||
</Home>
|
||||
<CustomDocument id=""1172"" parentID=""-1"" level=""1"" writerID=""0"" creatorID=""0"" nodeType=""1234"" template=""" + templateId + @""" sortOrder=""2"" createDate=""2012-07-16T15:26:59"" updateDate=""2012-07-18T14:23:35"" nodeName=""Test"" urlName=""test-page"" writerName=""admin"" creatorName=""admin"" path=""-1,1172"" isDoc="""" />
|
||||
</root>";
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.PublishedContentTestXml(1234, _node1173Guid);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
_dataTypes = dataTypes;
|
||||
|
||||
// configure the Home content type to be composed of another for tests.
|
||||
var compositionType = new ContentType(TestHelper.ShortStringHelper, -1)
|
||||
{
|
||||
Alias = "MyCompositionAlias"
|
||||
};
|
||||
contentTypes.First(x => x.Alias == "Home").AddContentType(compositionType);
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes: dataTypes);
|
||||
}
|
||||
|
||||
internal IPublishedContent GetNode(int id)
|
||||
// override to specify our own factory with custom types
|
||||
protected override IPublishedModelFactory PublishedModelFactory
|
||||
=> _publishedModelFactory ??= new PublishedModelFactory(
|
||||
new[] { typeof(Home), typeof(Anything), typeof(CustomDocument) },
|
||||
PublishedValueFallback);
|
||||
|
||||
[PublishedModel("Home")]
|
||||
internal class Home : PublishedContentModel
|
||||
{
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var doc = ctx.Content.GetById(id);
|
||||
Assert.IsNotNull(doc);
|
||||
return doc;
|
||||
public Home(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{ }
|
||||
|
||||
public bool UmbracoNaviHide => this.Value<bool>(Mock.Of<IPublishedValueFallback>(), "umbracoNaviHide");
|
||||
}
|
||||
|
||||
[PublishedModel("anything")]
|
||||
internal class Anything : PublishedContentModel
|
||||
{
|
||||
public Anything(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{ }
|
||||
}
|
||||
|
||||
[PublishedModel("CustomDocument")]
|
||||
internal class CustomDocument : PublishedContentModel
|
||||
{
|
||||
public CustomDocument(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{ }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetNodeByIds()
|
||||
{
|
||||
var ctx = GetUmbracoContext("/test");
|
||||
var contentById = ctx.Content.GetById(1173);
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
|
||||
var contentById = snapshot.Content.GetById(1173);
|
||||
Assert.IsNotNull(contentById);
|
||||
var contentByGuid = ctx.Content.GetById(_node1173Guid);
|
||||
var contentByGuid = snapshot.Content.GetById(_node1173Guid);
|
||||
Assert.IsNotNull(contentByGuid);
|
||||
Assert.AreEqual(contentById.Id, contentByGuid.Id);
|
||||
Assert.AreEqual(contentById.Key, contentByGuid.Key);
|
||||
|
||||
contentById = ctx.Content.GetById(666);
|
||||
contentById = snapshot.Content.GetById(666);
|
||||
Assert.IsNull(contentById);
|
||||
contentByGuid = ctx.Content.GetById(Guid.NewGuid());
|
||||
contentByGuid = snapshot.Content.GetById(Guid.NewGuid());
|
||||
Assert.IsNull(contentByGuid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter_Dynamic_Linq()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var items = doc.Children(VariationContextAccessor).Where(x => x.IsVisible(Mock.Of<IPublishedValueFallback>())).ToIndexedArray();
|
||||
|
||||
@@ -195,11 +110,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
if (item.Content.Id != 1178)
|
||||
{
|
||||
Assert.IsFalse(item.IsLast());
|
||||
Assert.IsFalse(item.IsLast(), $"The item {item.Content.Id} is last");
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(item.IsLast());
|
||||
Assert.IsTrue(item.IsLast(), $"The item {item.Content.Id} is not last");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,7 +122,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var items = doc
|
||||
.Children(VariationContextAccessor)
|
||||
@@ -243,30 +158,14 @@ namespace Umbraco.Tests.PublishedContent
|
||||
}
|
||||
}
|
||||
|
||||
[PublishedModel("Home")]
|
||||
internal class Home : PublishedContentModel
|
||||
{
|
||||
public Home(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{}
|
||||
}
|
||||
|
||||
[PublishedModel("anything")]
|
||||
internal class Anything : PublishedContentModel
|
||||
{
|
||||
public Anything(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
: base(content, fallback)
|
||||
{ }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Is_Last_From_Where_Filter2()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
var ct = doc.ContentType;
|
||||
|
||||
var items = doc.Children(VariationContextAccessor)
|
||||
.Select(x => x.CreateModel(Current.PublishedModelFactory)) // linq, returns IEnumerable<IPublishedContent>
|
||||
.Select(x => x.CreateModel(PublishedModelFactory)) // linq, returns IEnumerable<IPublishedContent>
|
||||
|
||||
// only way around this is to make sure every IEnumerable<T> extension
|
||||
// explicitely returns a PublishedContentSet, not an IEnumerable<T>
|
||||
@@ -295,7 +194,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Is_Last_From_Take()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var items = doc.Children(VariationContextAccessor).Take(4).ToIndexedArray();
|
||||
|
||||
@@ -315,7 +214,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Is_Last_From_Skip()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
foreach (var d in doc.Children(VariationContextAccessor).Skip(1).ToIndexedArray())
|
||||
{
|
||||
@@ -333,10 +232,10 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Is_Last_From_Concat()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var items = doc.Children(VariationContextAccessor)
|
||||
.Concat(new[] { GetNode(1175), GetNode(4444) })
|
||||
.Concat(new[] { GetContent(1175), GetContent(4444) })
|
||||
.ToIndexedArray();
|
||||
|
||||
foreach (var item in items)
|
||||
@@ -355,7 +254,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Descendants_Ordered_Properly()
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
var doc = GetContent(1046);
|
||||
|
||||
var expected = new[] { 1046, 1173, 1174, 117, 1177, 1178, 1179, 1176, 1175, 4444, 1172 };
|
||||
var exindex = 0;
|
||||
@@ -370,9 +269,11 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Get_Property_Value_Recursive()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
var rVal = doc.Value(Factory.GetRequiredService<IPublishedValueFallback>(), "testRecursive", fallback: Fallback.ToAncestors);
|
||||
var nullVal = doc.Value(Factory.GetRequiredService<IPublishedValueFallback>(), "DoNotFindThis", fallback: Fallback.ToAncestors);
|
||||
// TODO: We need to use a different fallback?
|
||||
|
||||
var doc = GetContent(1174);
|
||||
var rVal = doc.Value(PublishedValueFallback, "testRecursive", fallback: Fallback.ToAncestors);
|
||||
var nullVal = doc.Value(PublishedValueFallback, "DoNotFindThis", fallback: Fallback.ToAncestors);
|
||||
Assert.AreEqual("This is the recursive val", rVal);
|
||||
Assert.AreEqual(null, nullVal);
|
||||
}
|
||||
@@ -380,17 +281,17 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Get_Property_Value_Uses_Converter()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var propVal = doc.Value(Mock.Of<IPublishedValueFallback>(), "content");
|
||||
var propVal = doc.Value(PublishedValueFallback, "content");
|
||||
Assert.IsInstanceOf(typeof(IHtmlEncodedString), propVal);
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal.ToString());
|
||||
|
||||
var propVal2 = doc.Value<IHtmlEncodedString>(Mock.Of<IPublishedValueFallback>(), "content");
|
||||
var propVal2 = doc.Value<IHtmlEncodedString>(PublishedValueFallback, "content");
|
||||
Assert.IsInstanceOf(typeof(IHtmlEncodedString), propVal2);
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
|
||||
|
||||
var propVal3 = doc.Value(Mock.Of<IPublishedValueFallback>(), "Content");
|
||||
var propVal3 = doc.Value(PublishedValueFallback, "Content");
|
||||
Assert.IsInstanceOf(typeof(IHtmlEncodedString), propVal3);
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal3.ToString());
|
||||
}
|
||||
@@ -398,12 +299,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Complex_Linq()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var result = doc.Ancestors().OrderBy(x => x.Level)
|
||||
.Single()
|
||||
.Descendants(Mock.Of<IVariationContextAccessor>())
|
||||
.FirstOrDefault(x => x.Value<string>(Mock.Of<IPublishedValueFallback>(), "selectedNodes", defaultValue: "").Split(',').Contains("1173"));
|
||||
.FirstOrDefault(x => x.Value<string>(PublishedValueFallback, "selectedNodes", fallback: Fallback.ToDefaultValue, defaultValue: "").Split(',').Contains("1173"));
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
}
|
||||
@@ -411,16 +312,16 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Children_GroupBy_DocumentTypeAlias()
|
||||
{
|
||||
var home = new AutoPublishedContentType(Guid.NewGuid(), 22, "Home", new PublishedPropertyType[] { });
|
||||
var custom = new AutoPublishedContentType(Guid.NewGuid(), 23, "CustomDocument", new PublishedPropertyType[] { });
|
||||
var contentTypes = new Dictionary<string, PublishedContentType>
|
||||
{
|
||||
{ home.Alias, home },
|
||||
{ custom.Alias, custom }
|
||||
};
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = alias => contentTypes[alias];
|
||||
//var home = new AutoPublishedContentType(Guid.NewGuid(), 22, "Home", new PublishedPropertyType[] { });
|
||||
//var custom = new AutoPublishedContentType(Guid.NewGuid(), 23, "CustomDocument", new PublishedPropertyType[] { });
|
||||
//var contentTypes = new Dictionary<string, PublishedContentType>
|
||||
//{
|
||||
// { home.Alias, home },
|
||||
// { custom.Alias, custom }
|
||||
//};
|
||||
//ContentTypesCache.GetPublishedContentTypeByAlias = alias => contentTypes[alias];
|
||||
|
||||
var doc = GetNode(1046);
|
||||
var doc = GetContent(1046);
|
||||
|
||||
var found1 = doc.Children(VariationContextAccessor).GroupBy(x => x.ContentType.Alias).ToArray();
|
||||
|
||||
@@ -432,16 +333,16 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Children_Where_DocumentTypeAlias()
|
||||
{
|
||||
var home = new AutoPublishedContentType(Guid.NewGuid(), 22, "Home", new PublishedPropertyType[] { });
|
||||
var custom = new AutoPublishedContentType(Guid.NewGuid(), 23, "CustomDocument", new PublishedPropertyType[] { });
|
||||
var contentTypes = new Dictionary<string, PublishedContentType>
|
||||
{
|
||||
{ home.Alias, home },
|
||||
{ custom.Alias, custom }
|
||||
};
|
||||
ContentTypesCache.GetPublishedContentTypeByAlias = alias => contentTypes[alias];
|
||||
//var home = new AutoPublishedContentType(Guid.NewGuid(), 22, "Home", new PublishedPropertyType[] { });
|
||||
//var custom = new AutoPublishedContentType(Guid.NewGuid(), 23, "CustomDocument", new PublishedPropertyType[] { });
|
||||
//var contentTypes = new Dictionary<string, PublishedContentType>
|
||||
//{
|
||||
// { home.Alias, home },
|
||||
// { custom.Alias, custom }
|
||||
//};
|
||||
//ContentTypesCache.GetPublishedContentTypeByAlias = alias => contentTypes[alias];
|
||||
|
||||
var doc = GetNode(1046);
|
||||
var doc = GetContent(1046);
|
||||
|
||||
var found1 = doc.Children(VariationContextAccessor).Where(x => x.ContentType.Alias == "CustomDocument");
|
||||
var found2 = doc.Children(VariationContextAccessor).Where(x => x.ContentType.Alias == "Home");
|
||||
@@ -453,7 +354,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Children_Order_By_Update_Date()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var ordered = doc.Children(VariationContextAccessor).OrderBy(x => x.UpdateDate);
|
||||
|
||||
@@ -468,12 +369,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void FirstChild()
|
||||
{
|
||||
var doc = GetNode(1173); // has child nodes
|
||||
var doc = GetContent(1173); // has child nodes
|
||||
Assert.IsNotNull(doc.FirstChild(Mock.Of<IVariationContextAccessor>()));
|
||||
Assert.IsNotNull(doc.FirstChild(Mock.Of<IVariationContextAccessor>(), x => true));
|
||||
Assert.IsNotNull(doc.FirstChild<IPublishedContent>(Mock.Of<IVariationContextAccessor>()));
|
||||
|
||||
doc = GetNode(1175); // does not have child nodes
|
||||
doc = GetContent(1175); // does not have child nodes
|
||||
Assert.IsNull(doc.FirstChild(Mock.Of<IVariationContextAccessor>()));
|
||||
Assert.IsNull(doc.FirstChild(Mock.Of<IVariationContextAccessor>(), x => true));
|
||||
Assert.IsNull(doc.FirstChild<IPublishedContent>(Mock.Of<IVariationContextAccessor>()));
|
||||
@@ -482,7 +383,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void FirstChildAsT()
|
||||
{
|
||||
var doc = GetNode(1046); // has child nodes
|
||||
var doc = GetContent(1046); // has child nodes
|
||||
|
||||
var model = doc.FirstChild<Home>(Mock.Of<IVariationContextAccessor>(), x => true); // predicate
|
||||
|
||||
@@ -491,7 +392,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.IsInstanceOf<Home>(model);
|
||||
Assert.IsInstanceOf<IPublishedContent>(model);
|
||||
|
||||
doc = GetNode(1175); // does not have child nodes
|
||||
doc = GetContent(1175); // does not have child nodes
|
||||
Assert.IsNull(doc.FirstChild<Anything>(Mock.Of<IVariationContextAccessor>()));
|
||||
Assert.IsNull(doc.FirstChild<Anything>(Mock.Of<IVariationContextAccessor>(), x => true));
|
||||
}
|
||||
@@ -499,7 +400,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void IsComposedOf()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var isComposedOf = doc.IsComposedOf("MyCompositionAlias");
|
||||
|
||||
@@ -509,7 +410,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void HasProperty()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var hasProp = doc.HasProperty(Constants.Conventions.Content.UrlAlias);
|
||||
|
||||
@@ -519,7 +420,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void HasValue()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var hasValue = doc.HasValue(Mock.Of<IPublishedValueFallback>(), Constants.Conventions.Content.UrlAlias);
|
||||
var noValue = doc.HasValue(Mock.Of<IPublishedValueFallback>(), "blahblahblah");
|
||||
@@ -531,7 +432,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Ancestors_Where_Visible()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
var doc = GetContent(1174);
|
||||
|
||||
var whereVisible = doc.Ancestors().Where(x => x.IsVisible(Mock.Of<IPublishedValueFallback>()));
|
||||
Assert.AreEqual(1, whereVisible.Count());
|
||||
@@ -541,8 +442,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Visible()
|
||||
{
|
||||
var hidden = GetNode(1046);
|
||||
var visible = GetNode(1173);
|
||||
var hidden = GetContent(1046);
|
||||
var visible = GetContent(1173);
|
||||
|
||||
Assert.IsFalse(hidden.IsVisible(Mock.Of<IPublishedValueFallback>()));
|
||||
Assert.IsTrue(visible.IsVisible(Mock.Of<IPublishedValueFallback>()));
|
||||
@@ -551,7 +452,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Ancestor_Or_Self()
|
||||
{
|
||||
var doc = GetNode(1173);
|
||||
var doc = GetContent(1173);
|
||||
|
||||
var result = doc.AncestorOrSelf();
|
||||
|
||||
@@ -564,7 +465,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void U4_4559()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
var doc = GetContent(1174);
|
||||
var result = doc.AncestorOrSelf(1);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(1046, result.Id);
|
||||
@@ -573,27 +474,27 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Ancestors_Or_Self()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
var doc = GetContent(1174);
|
||||
|
||||
var result = doc.AncestorsOrSelf().ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(3, result.Length);
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).GetId()).ContainsAll(new dynamic[] { 1174, 1173, 1046 }));
|
||||
Assert.IsTrue(result.Select(x => x.Id).ContainsAll(new [] { 1174, 1173, 1046 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ancestors()
|
||||
{
|
||||
var doc = GetNode(1174);
|
||||
var doc = GetContent(1174);
|
||||
|
||||
var result = doc.Ancestors().ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(2, result.Length);
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).GetId()).ContainsAll(new dynamic[] { 1173, 1046 }));
|
||||
Assert.IsTrue(result.Select(x => x.Id).ContainsAll(new [] { 1173, 1046 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -607,12 +508,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// -- Custom Doc4: 117 (parent 1173)
|
||||
// - Custom Doc3: 1172 (no parent)
|
||||
|
||||
var home = GetNode(1173);
|
||||
var root = GetNode(1046);
|
||||
var customDoc = GetNode(1178);
|
||||
var customDoc2 = GetNode(1179);
|
||||
var customDoc3 = GetNode(1172);
|
||||
var customDoc4 = GetNode(117);
|
||||
var home = GetContent(1173);
|
||||
var root = GetContent(1046);
|
||||
var customDoc = GetContent(1178);
|
||||
var customDoc2 = GetContent(1179);
|
||||
var customDoc3 = GetContent(1172);
|
||||
var customDoc4 = GetContent(117);
|
||||
|
||||
Assert.IsTrue(root.IsAncestor(customDoc4));
|
||||
Assert.IsFalse(root.IsAncestor(customDoc3));
|
||||
@@ -656,12 +557,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// -- Custom Doc4: 117 (parent 1173)
|
||||
// - Custom Doc3: 1172 (no parent)
|
||||
|
||||
var home = GetNode(1173);
|
||||
var root = GetNode(1046);
|
||||
var customDoc = GetNode(1178);
|
||||
var customDoc2 = GetNode(1179);
|
||||
var customDoc3 = GetNode(1172);
|
||||
var customDoc4 = GetNode(117);
|
||||
var home = GetContent(1173);
|
||||
var root = GetContent(1046);
|
||||
var customDoc = GetContent(1178);
|
||||
var customDoc2 = GetContent(1179);
|
||||
var customDoc3 = GetContent(1172);
|
||||
var customDoc4 = GetContent(117);
|
||||
|
||||
Assert.IsTrue(root.IsAncestorOrSelf(customDoc4));
|
||||
Assert.IsFalse(root.IsAncestorOrSelf(customDoc3));
|
||||
@@ -699,27 +600,27 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Descendants_Or_Self()
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
var doc = GetContent(1046);
|
||||
|
||||
var result = doc.DescendantsOrSelf(Mock.Of<IVariationContextAccessor>()).ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(10, result.Count());
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).GetId()).ContainsAll(new dynamic[] { 1046, 1173, 1174, 1176, 1175 }));
|
||||
Assert.IsTrue(result.Select(x => x.Id).ContainsAll(new [] { 1046, 1173, 1174, 1176, 1175 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Descendants()
|
||||
{
|
||||
var doc = GetNode(1046);
|
||||
var doc = GetContent(1046);
|
||||
|
||||
var result = doc.Descendants(Mock.Of<IVariationContextAccessor>()).ToArray();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual(9, result.Count());
|
||||
Assert.IsTrue(result.Select(x => ((dynamic)x).GetId()).ContainsAll(new dynamic[] { 1173, 1174, 1176, 1175, 4444 }));
|
||||
Assert.IsTrue(result.Select(x => x.Id).ContainsAll(new [] { 1173, 1174, 1176, 1175, 4444 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -733,12 +634,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// -- Custom Doc4: 117 (parent 1173)
|
||||
// - Custom Doc3: 1172 (no parent)
|
||||
|
||||
var home = GetNode(1173);
|
||||
var root = GetNode(1046);
|
||||
var customDoc = GetNode(1178);
|
||||
var customDoc2 = GetNode(1179);
|
||||
var customDoc3 = GetNode(1172);
|
||||
var customDoc4 = GetNode(117);
|
||||
var home = GetContent(1173);
|
||||
var root = GetContent(1046);
|
||||
var customDoc = GetContent(1178);
|
||||
var customDoc2 = GetContent(1179);
|
||||
var customDoc3 = GetContent(1172);
|
||||
var customDoc4 = GetContent(117);
|
||||
|
||||
Assert.IsFalse(root.IsDescendant(root));
|
||||
Assert.IsFalse(root.IsDescendant(home));
|
||||
@@ -782,12 +683,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// -- Custom Doc4: 117 (parent 1173)
|
||||
// - Custom Doc3: 1172 (no parent)
|
||||
|
||||
var home = GetNode(1173);
|
||||
var root = GetNode(1046);
|
||||
var customDoc = GetNode(1178);
|
||||
var customDoc2 = GetNode(1179);
|
||||
var customDoc3 = GetNode(1172);
|
||||
var customDoc4 = GetNode(117);
|
||||
var home = GetContent(1173);
|
||||
var root = GetContent(1046);
|
||||
var customDoc = GetContent(1178);
|
||||
var customDoc2 = GetContent(1179);
|
||||
var customDoc3 = GetContent(1172);
|
||||
var customDoc4 = GetContent(117);
|
||||
|
||||
Assert.IsTrue(root.IsDescendantOrSelf(root));
|
||||
Assert.IsFalse(root.IsDescendantOrSelf(home));
|
||||
@@ -830,39 +731,40 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// --- Level1.1.2: 117 (parent 1173)
|
||||
// --- Level1.1.3: 1177 (parent 1173)
|
||||
// --- Level1.1.4: 1178 (parent 1173)
|
||||
// ---- Level1.1.4.1: 1179 (parent 1178)
|
||||
// --- Level1.1.5: 1176 (parent 1173)
|
||||
// -- Level1.2: 1175 (parent 1046)
|
||||
// -- Level1.3: 4444 (parent 1046)
|
||||
var root = GetNode(1046);
|
||||
var level1_1 = GetNode(1173);
|
||||
var level1_1_1 = GetNode(1174);
|
||||
var level1_1_2 = GetNode(117);
|
||||
var level1_1_3 = GetNode(1177);
|
||||
var level1_1_4 = GetNode(1178);
|
||||
var level1_1_5 = GetNode(1176);
|
||||
var level1_2 = GetNode(1175);
|
||||
var level1_3 = GetNode(4444);
|
||||
// - Root : 1172 (no parent)
|
||||
|
||||
_publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot.Content.GetAtRoot(It.IsAny<string>())).Returns(new []{root});
|
||||
var root = GetContent(1046);
|
||||
var level1_1 = GetContent(1173);
|
||||
var level1_1_1 = GetContent(1174);
|
||||
var level1_1_2 = GetContent(117);
|
||||
var level1_1_3 = GetContent(1177);
|
||||
var level1_1_4 = GetContent(1178);
|
||||
var level1_1_5 = GetContent(1176);
|
||||
var level1_2 = GetContent(1175);
|
||||
var level1_3 = GetContent(4444);
|
||||
var root2 = GetContent(1172);
|
||||
|
||||
var variationContextAccessor = Factory.GetRequiredService<IVariationContextAccessor>();
|
||||
var publishedSnapshot = _publishedSnapshotAccessorMock.Object.PublishedSnapshot;
|
||||
var publishedSnapshot = GetPublishedSnapshot();
|
||||
|
||||
CollectionAssertAreEqual(new []{root}, root.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { root, root2 }, root.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
|
||||
CollectionAssertAreEqual( new []{level1_1, level1_2, level1_3}, level1_1.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1, level1_2, level1_3}, level1_2.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1, level1_2, level1_3}, level1_3.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1, level1_2, level1_3 }, level1_1.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1, level1_2, level1_3 }, level1_2.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1, level1_2, level1_3 }, level1_3.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5}, level1_1_1.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5}, level1_1_2.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5}, level1_1_3.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5}, level1_1_4.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5}, level1_1_5.SiblingsAndSelf(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5 }, level1_1_1.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5 }, level1_1_2.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5 }, level1_1_3.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5 }, level1_1_4.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_4, level1_1_5 }, level1_1_5.SiblingsAndSelf(publishedSnapshot, VariationContextAccessor));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Test]
|
||||
public void Siblings()
|
||||
{
|
||||
// Structure:
|
||||
@@ -872,40 +774,41 @@ namespace Umbraco.Tests.PublishedContent
|
||||
// --- Level1.1.2: 117 (parent 1173)
|
||||
// --- Level1.1.3: 1177 (parent 1173)
|
||||
// --- Level1.1.4: 1178 (parent 1173)
|
||||
// ---- Level1.1.4.1: 1179 (parent 1178)
|
||||
// --- Level1.1.5: 1176 (parent 1173)
|
||||
// -- Level1.2: 1175 (parent 1046)
|
||||
// -- Level1.3: 4444 (parent 1046)
|
||||
var root = GetNode(1046);
|
||||
var level1_1 = GetNode(1173);
|
||||
var level1_1_1 = GetNode(1174);
|
||||
var level1_1_2 = GetNode(117);
|
||||
var level1_1_3 = GetNode(1177);
|
||||
var level1_1_4 = GetNode(1178);
|
||||
var level1_1_5 = GetNode(1176);
|
||||
var level1_2 = GetNode(1175);
|
||||
var level1_3 = GetNode(4444);
|
||||
// - Root : 1172 (no parent)
|
||||
|
||||
_publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot.Content.GetAtRoot(It.IsAny<string>())).Returns(new []{root});
|
||||
var root = GetContent(1046);
|
||||
var level1_1 = GetContent(1173);
|
||||
var level1_1_1 = GetContent(1174);
|
||||
var level1_1_2 = GetContent(117);
|
||||
var level1_1_3 = GetContent(1177);
|
||||
var level1_1_4 = GetContent(1178);
|
||||
var level1_1_5 = GetContent(1176);
|
||||
var level1_2 = GetContent(1175);
|
||||
var level1_3 = GetContent(4444);
|
||||
var root2 = GetContent(1172);
|
||||
|
||||
var variationContextAccessor = Factory.GetRequiredService<IVariationContextAccessor>();
|
||||
var publishedSnapshot = _publishedSnapshotAccessorMock.Object.PublishedSnapshot;
|
||||
var publishedSnapshot = GetPublishedSnapshot();
|
||||
|
||||
CollectionAssertAreEqual(new IPublishedContent[0], root.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { root2 }, root.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
|
||||
CollectionAssertAreEqual( new []{level1_2, level1_3}, level1_1.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1, level1_3}, level1_2.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1, level1_2}, level1_3.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_2, level1_3 }, level1_1.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1, level1_3 }, level1_2.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1, level1_2 }, level1_3.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
|
||||
CollectionAssertAreEqual( new []{ level1_1_2, level1_1_3, level1_1_4, level1_1_5}, level1_1_1.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_3, level1_1_4, level1_1_5}, level1_1_2.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_4, level1_1_5}, level1_1_3.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_5}, level1_1_4.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual( new []{level1_1_1, level1_1_2, level1_1_3, level1_1_4}, level1_1_5.Siblings(publishedSnapshot, variationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_2, level1_1_3, level1_1_4, level1_1_5 }, level1_1_1.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_3, level1_1_4, level1_1_5 }, level1_1_2.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_4, level1_1_5 }, level1_1_3.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_5 }, level1_1_4.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
CollectionAssertAreEqual(new[] { level1_1_1, level1_1_2, level1_1_3, level1_1_4 }, level1_1_5.Siblings(publishedSnapshot, VariationContextAccessor));
|
||||
|
||||
}
|
||||
|
||||
private void CollectionAssertAreEqual<T>(IEnumerable<T> expected, IEnumerable<T> actual)
|
||||
where T: IPublishedContent
|
||||
where T : IPublishedContent
|
||||
{
|
||||
var e = expected.Select(x => x.Id);
|
||||
var a = actual.Select(x => x.Id);
|
||||
@@ -915,37 +818,26 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void FragmentProperty()
|
||||
{
|
||||
var factory = Factory.GetRequiredService<IPublishedContentTypeFactory>() as PublishedContentTypeFactory;
|
||||
|
||||
IEnumerable<IPublishedPropertyType> CreatePropertyTypes(IPublishedContentType contentType)
|
||||
{
|
||||
yield return factory.CreatePropertyType(contentType, "detached", 1003);
|
||||
yield return PublishedContentTypeFactory.CreatePropertyType(contentType, "detached", _dataTypes[0].Id);
|
||||
}
|
||||
|
||||
var ct = factory.CreateContentType(Guid.NewGuid(), 0, "alias", CreatePropertyTypes);
|
||||
var ct = PublishedContentTypeFactory.CreateContentType(Guid.NewGuid(), 0, "alias", CreatePropertyTypes);
|
||||
var pt = ct.GetPropertyType("detached");
|
||||
var prop = new PublishedElementPropertyBase(pt, null, false, PropertyCacheLevel.None, 5548);
|
||||
Assert.IsInstanceOf<int>(prop.GetValue());
|
||||
Assert.AreEqual(5548, prop.GetValue());
|
||||
}
|
||||
|
||||
public void Fragment1()
|
||||
{
|
||||
var type = ContentTypesCache.Get(PublishedItemType.Content, "detachedSomething");
|
||||
var values = new Dictionary<string, object>();
|
||||
var f = new PublishedElement(type, Guid.NewGuid(), values, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Fragment2()
|
||||
{
|
||||
var factory = Factory.GetRequiredService<IPublishedContentTypeFactory>() as PublishedContentTypeFactory;
|
||||
|
||||
IEnumerable<IPublishedPropertyType> CreatePropertyTypes(IPublishedContentType contentType)
|
||||
{
|
||||
yield return factory.CreatePropertyType(contentType, "legend", 1004);
|
||||
yield return factory.CreatePropertyType(contentType, "image", 1005);
|
||||
yield return factory.CreatePropertyType(contentType, "size", 1003);
|
||||
yield return PublishedContentTypeFactory.CreatePropertyType(contentType, "legend", _dataTypes[0].Id);
|
||||
yield return PublishedContentTypeFactory.CreatePropertyType(contentType, "image", _dataTypes[0].Id);
|
||||
yield return PublishedContentTypeFactory.CreatePropertyType(contentType, "size", _dataTypes[0].Id);
|
||||
}
|
||||
|
||||
const string val1 = "boom bam";
|
||||
@@ -954,7 +846,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
var guid = Guid.NewGuid();
|
||||
|
||||
var ct = factory.CreateContentType(Guid.NewGuid(), 0, "alias", CreatePropertyTypes);
|
||||
var ct = PublishedContentTypeFactory.CreateContentType(Guid.NewGuid(), 0, "alias", CreatePropertyTypes);
|
||||
|
||||
var c = new ImageWithLegendModel(ct, guid, new Dictionary<string, object>
|
||||
{
|
||||
@@ -967,6 +859,87 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.AreEqual(val3, c.Size);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void First()
|
||||
{
|
||||
var publishedSnapshot = GetPublishedSnapshot();
|
||||
var content = publishedSnapshot.Content.GetAtRoot().First();
|
||||
Assert.AreEqual("Home", content.Name(VariationContextAccessor));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Distinct()
|
||||
{
|
||||
var items = GetContent(1173)
|
||||
.Children(VariationContextAccessor)
|
||||
.Distinct()
|
||||
.Distinct()
|
||||
.ToIndexedArray();
|
||||
|
||||
Assert.AreEqual(5, items.Length);
|
||||
|
||||
IndexedArrayItem<IPublishedContent> item = items[0];
|
||||
Assert.AreEqual(1174, item.Content.Id);
|
||||
Assert.IsTrue(item.IsFirst());
|
||||
Assert.IsFalse(item.IsLast());
|
||||
|
||||
item = items[^1];
|
||||
Assert.AreEqual(1176, item.Content.Id);
|
||||
Assert.IsFalse(item.IsFirst());
|
||||
Assert.IsTrue(item.IsLast());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OfType1()
|
||||
{
|
||||
var publishedSnapshot = GetPublishedSnapshot();
|
||||
var items = publishedSnapshot.Content.GetAtRoot()
|
||||
.OfType<Home>()
|
||||
.Distinct()
|
||||
.ToIndexedArray();
|
||||
Assert.AreEqual(1, items.Length);
|
||||
Assert.IsInstanceOf<Home>(items.First().Content);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OfType2()
|
||||
{
|
||||
var publishedSnapshot = GetPublishedSnapshot();
|
||||
var content = publishedSnapshot.Content.GetAtRoot()
|
||||
.OfType<CustomDocument>()
|
||||
.Distinct()
|
||||
.ToIndexedArray();
|
||||
Assert.AreEqual(1, content.Length);
|
||||
Assert.IsInstanceOf<CustomDocument>(content.First().Content);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OfType()
|
||||
{
|
||||
var content = GetContent(1173)
|
||||
.Children(VariationContextAccessor)
|
||||
.OfType<Home>()
|
||||
.First(x => x.UmbracoNaviHide == true);
|
||||
Assert.AreEqual(1176, content.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Position()
|
||||
{
|
||||
var items = GetContent(1173).Children(VariationContextAccessor)
|
||||
.Where(x => x.Value<int?>(Mock.Of<IPublishedValueFallback>(), "umbracoNaviHide") == 0)
|
||||
.ToIndexedArray();
|
||||
|
||||
Assert.AreEqual(3, items.Length);
|
||||
|
||||
Assert.IsTrue(items.First().IsFirst());
|
||||
Assert.IsFalse(items.First().IsLast());
|
||||
Assert.IsFalse(items.Skip(1).First().IsFirst());
|
||||
Assert.IsFalse(items.Skip(1).First().IsLast());
|
||||
Assert.IsFalse(items.Skip(2).First().IsFirst());
|
||||
Assert.IsTrue(items.Skip(2).First().IsLast());
|
||||
}
|
||||
|
||||
class ImageWithLegendModel : PublishedElement
|
||||
{
|
||||
public ImageWithLegendModel(IPublishedContentType contentType, Guid fragmentKey, Dictionary<string, object> values, bool previewing)
|
||||
@@ -980,5 +953,31 @@ namespace Umbraco.Tests.PublishedContent
|
||||
|
||||
public int Size => this.Value<int>(Mock.Of<IPublishedValueFallback>(), "size");
|
||||
}
|
||||
|
||||
//[PublishedModel("ContentType2")]
|
||||
//public class ContentType2 : PublishedContentModel
|
||||
//{
|
||||
// #region Plumbing
|
||||
|
||||
// public ContentType2(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
// : base(content, fallback)
|
||||
// { }
|
||||
|
||||
// #endregion
|
||||
|
||||
// public int Prop1 => this.Value<int>(Mock.Of<IPublishedValueFallback>(), "prop1");
|
||||
//}
|
||||
|
||||
//[PublishedModel("ContentType2Sub")]
|
||||
//public class ContentType2Sub : ContentType2
|
||||
//{
|
||||
// #region Plumbing
|
||||
|
||||
// public ContentType2Sub(IPublishedContent content, IPublishedValueFallback fallback)
|
||||
// : base(content, fallback)
|
||||
// { }
|
||||
|
||||
// #endregion
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests the typed extension methods on IPublishedContent using the DefaultPublishedMediaStore
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class PublishedMediaTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
var dataTypes = GetDefaultDataTypes().ToList();
|
||||
var serializer = new ConfigurationEditorJsonSerializer();
|
||||
var rteDataType = new DataType(new VoidEditor("RTE", Mock.Of<IDataValueEditorFactory>()), serializer) { Id = 4 };
|
||||
dataTypes.Add(rteDataType);
|
||||
_dataTypes = dataTypes.ToArray();
|
||||
|
||||
_propertyDataTypes = new()
|
||||
{
|
||||
// defaults will just use the first one
|
||||
[string.Empty] = _dataTypes[0],
|
||||
|
||||
// content uses the RTE
|
||||
["content"] = _dataTypes[1]
|
||||
};
|
||||
}
|
||||
|
||||
private Dictionary<string, IDataType> _propertyDataTypes;
|
||||
private DataType[] _dataTypes;
|
||||
|
||||
private ContentNodeKit CreateRoot(out MediaType mediaType)
|
||||
{
|
||||
mediaType = new MediaType(ShortStringHelper, -1);
|
||||
|
||||
ContentData item1Data = new ContentDataBuilder()
|
||||
.WithName("Content 1")
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("content", "<div>This is some content</div>")
|
||||
.Build())
|
||||
// build with a dynamically created media type
|
||||
.Build(ShortStringHelper, _propertyDataTypes, mediaType, "image2");
|
||||
|
||||
ContentNodeKit item1 = ContentNodeKitBuilder.CreateWithContent(
|
||||
mediaType.Id,
|
||||
1, "-1,1",
|
||||
draftData: item1Data,
|
||||
publishedData: item1Data);
|
||||
|
||||
return item1;
|
||||
}
|
||||
|
||||
private IEnumerable<ContentNodeKit> CreateChildren(
|
||||
int startId,
|
||||
ContentNodeKit parent,
|
||||
IMediaType mediaType,
|
||||
int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var id = startId + i + 1;
|
||||
|
||||
ContentData item1Data = new ContentDataBuilder()
|
||||
.WithName("Child " + id)
|
||||
.WithProperties(new PropertyDataBuilder()
|
||||
.WithPropertyData("content", "<div>This is some content</div>")
|
||||
.Build())
|
||||
.Build();
|
||||
|
||||
var parentPath = parent.Node.Path;
|
||||
|
||||
ContentNodeKit item1 = ContentNodeKitBuilder.CreateWithContent(
|
||||
mediaType.Id,
|
||||
id, $"{parentPath},{id}",
|
||||
draftData: item1Data,
|
||||
publishedData: item1Data);
|
||||
|
||||
yield return item1;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeWithHierarchy(
|
||||
out int rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren)
|
||||
{
|
||||
var cache = new List<ContentNodeKit>();
|
||||
var root = CreateRoot(out MediaType mediaType);
|
||||
firstLevelChildren = CreateChildren(10, root, mediaType, 3).ToList();
|
||||
secondLevelChildren = CreateChildren(20, firstLevelChildren[0], mediaType, 3).ToList();
|
||||
cache.Add(root);
|
||||
cache.AddRange(firstLevelChildren);
|
||||
cache.AddRange(secondLevelChildren);
|
||||
InitializedCache(null, null, _dataTypes, cache, new[] { mediaType });
|
||||
rootId = root.Node.Id;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Property_Value_Uses_Converter()
|
||||
{
|
||||
var cache = CreateRoot(out MediaType mediaType);
|
||||
InitializedCache(null, null, _dataTypes.ToArray(), new[] { cache }, new[] { mediaType });
|
||||
|
||||
var publishedMedia = GetMedia(1);
|
||||
|
||||
var propVal = publishedMedia.Value(PublishedValueFallback, "content");
|
||||
Assert.IsInstanceOf<IHtmlEncodedString>(propVal);
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal.ToString());
|
||||
|
||||
var propVal2 = publishedMedia.Value<IHtmlEncodedString>(PublishedValueFallback, "content");
|
||||
Assert.IsInstanceOf<IHtmlEncodedString>(propVal2);
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal2.ToString());
|
||||
|
||||
var propVal3 = publishedMedia.Value(PublishedValueFallback, "Content");
|
||||
Assert.IsInstanceOf<IHtmlEncodedString>(propVal3);
|
||||
Assert.AreEqual("<div>This is some content</div>", propVal3.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Children()
|
||||
{
|
||||
InitializeWithHierarchy(
|
||||
out var rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren);
|
||||
|
||||
var publishedMedia = GetMedia(rootId);
|
||||
|
||||
var rootChildren = publishedMedia.Children(VariationContextAccessor);
|
||||
Assert.IsTrue(rootChildren.Select(x => x.Id).ContainsAll(firstLevelChildren.Select(x => x.Node.Id)));
|
||||
|
||||
var publishedChild1 = GetMedia(firstLevelChildren[0].Node.Id);
|
||||
var subChildren = publishedChild1.Children(VariationContextAccessor);
|
||||
Assert.IsTrue(subChildren.Select(x => x.Id).ContainsAll(secondLevelChildren.Select(x => x.Node.Id)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Descendants()
|
||||
{
|
||||
InitializeWithHierarchy(
|
||||
out var rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren);
|
||||
|
||||
var publishedMedia = GetMedia(rootId);
|
||||
var rootDescendants = publishedMedia.Descendants(VariationContextAccessor);
|
||||
|
||||
var descendentIds = firstLevelChildren.Select(x => x.Node.Id).Concat(secondLevelChildren.Select(x => x.Node.Id));
|
||||
|
||||
Assert.IsTrue(rootDescendants.Select(x => x.Id).ContainsAll(descendentIds));
|
||||
|
||||
var publishedChild1 = GetMedia(firstLevelChildren[0].Node.Id);
|
||||
var subDescendants = publishedChild1.Descendants(VariationContextAccessor);
|
||||
Assert.IsTrue(subDescendants.Select(x => x.Id).ContainsAll(secondLevelChildren.Select(x => x.Node.Id)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DescendantsOrSelf()
|
||||
{
|
||||
InitializeWithHierarchy(
|
||||
out var rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren);
|
||||
|
||||
var publishedMedia = GetMedia(rootId);
|
||||
var rootDescendantsOrSelf = publishedMedia.DescendantsOrSelf(VariationContextAccessor);
|
||||
var descendentAndSelfIds = firstLevelChildren.Select(x => x.Node.Id)
|
||||
.Concat(secondLevelChildren.Select(x => x.Node.Id))
|
||||
.Append(rootId);
|
||||
|
||||
Assert.IsTrue(rootDescendantsOrSelf.Select(x => x.Id).ContainsAll(descendentAndSelfIds));
|
||||
|
||||
var publishedChild1 = GetMedia(firstLevelChildren[0].Node.Id);
|
||||
var subDescendantsOrSelf = publishedChild1.DescendantsOrSelf(VariationContextAccessor);
|
||||
Assert.IsTrue(subDescendantsOrSelf.Select(x => x.Id).ContainsAll(
|
||||
secondLevelChildren.Select(x => x.Node.Id).Append(firstLevelChildren[0].Node.Id)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parent()
|
||||
{
|
||||
InitializeWithHierarchy(
|
||||
out var rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren);
|
||||
|
||||
var publishedMedia = GetMedia(rootId);
|
||||
Assert.AreEqual(null, publishedMedia.Parent);
|
||||
|
||||
var publishedChild1 = GetMedia(firstLevelChildren[0].Node.Id);
|
||||
Assert.AreEqual(publishedMedia.Id, publishedChild1.Parent.Id);
|
||||
|
||||
var publishedSubChild1 = GetMedia(secondLevelChildren[0].Node.Id);
|
||||
Assert.AreEqual(firstLevelChildren[0].Node.Id, publishedSubChild1.Parent.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ancestors()
|
||||
{
|
||||
InitializeWithHierarchy(
|
||||
out var rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren);
|
||||
|
||||
var publishedSubChild1 = GetMedia(secondLevelChildren[0].Node.Id);
|
||||
Assert.IsTrue(publishedSubChild1.Ancestors().Select(x => x.Id)
|
||||
.ContainsAll(new[] { firstLevelChildren[0].Node.Id, rootId }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AncestorsOrSelf()
|
||||
{
|
||||
InitializeWithHierarchy(
|
||||
out var rootId,
|
||||
out IReadOnlyList<ContentNodeKit> firstLevelChildren,
|
||||
out IReadOnlyList<ContentNodeKit> secondLevelChildren);
|
||||
|
||||
var publishedSubChild1 = GetMedia(secondLevelChildren[0].Node.Id);
|
||||
Assert.IsTrue(publishedSubChild1.AncestorsOrSelf().Select(x => x.Id)
|
||||
.ContainsAll(new[] { secondLevelChildren[0].Node.Id, firstLevelChildren[0].Node.Id, rootId }));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PublishedCache;
|
||||
using Umbraco.Cms.Core.Services.Changes;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache.DataSource;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
|
||||
|
||||
[TestFixture]
|
||||
public class PublishedSnapshotServiceContentTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
private ContentType _contentType;
|
||||
private PropertyType _propertyType;
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
_propertyType = new PropertyType(TestHelper.ShortStringHelper, "Umbraco.Void.Editor", ValueStorageType.Nvarchar) { Alias = "prop", DataTypeId = 3, Variations = ContentVariation.Culture };
|
||||
_contentType = new ContentType(TestHelper.ShortStringHelper, -1) { Id = 2, Alias = "alias-ct", Variations = ContentVariation.Culture };
|
||||
_contentType.AddPropertyType(_propertyType);
|
||||
|
||||
var contentTypes = new[]
|
||||
{
|
||||
_contentType
|
||||
};
|
||||
|
||||
InitializedCache(new[] { CreateKit() }, contentTypes);
|
||||
}
|
||||
|
||||
private ContentNodeKit CreateKit()
|
||||
{
|
||||
var draftData = new ContentDataBuilder()
|
||||
.WithName("It Works2!")
|
||||
.WithPublished(false)
|
||||
.WithProperties(new Dictionary<string, PropertyData[]>
|
||||
{
|
||||
["prop"] = new[]
|
||||
{
|
||||
new PropertyData { Culture = "", Segment = "", Value = "val2" },
|
||||
new PropertyData { Culture = "fr-FR", Segment = "", Value = "val-fr2" },
|
||||
new PropertyData { Culture = "en-UK", Segment = "", Value = "val-uk2" },
|
||||
new PropertyData { Culture = "dk-DA", Segment = "", Value = "val-da2" },
|
||||
new PropertyData { Culture = "de-DE", Segment = "", Value = "val-de2" }
|
||||
}
|
||||
})
|
||||
.WithCultureInfos(new Dictionary<string, CultureVariation>
|
||||
{
|
||||
// draft data = everything, and IsDraft indicates what's edited
|
||||
["fr-FR"] = new CultureVariation { Name = "name-fr2", IsDraft = true, Date = new DateTime(2018, 01, 03, 01, 00, 00) },
|
||||
["en-UK"] = new CultureVariation { Name = "name-uk2", IsDraft = true, Date = new DateTime(2018, 01, 04, 01, 00, 00) },
|
||||
["dk-DA"] = new CultureVariation { Name = "name-da2", IsDraft = true, Date = new DateTime(2018, 01, 05, 01, 00, 00) },
|
||||
["de-DE"] = new CultureVariation { Name = "name-de1", IsDraft = false, Date = new DateTime(2018, 01, 02, 01, 00, 00) }
|
||||
})
|
||||
.Build();
|
||||
|
||||
var publishedData = new ContentDataBuilder()
|
||||
.WithName("It Works1!")
|
||||
.WithPublished(true)
|
||||
.WithProperties(new Dictionary<string, PropertyData[]>
|
||||
{
|
||||
["prop"] = new[]
|
||||
{
|
||||
new PropertyData { Culture = "", Segment = "", Value = "val1" },
|
||||
new PropertyData { Culture = "fr-FR", Segment = "", Value = "val-fr1" },
|
||||
new PropertyData { Culture = "en-UK", Segment = "", Value = "val-uk1" }
|
||||
}
|
||||
})
|
||||
.WithCultureInfos(new Dictionary<string, CultureVariation>
|
||||
{
|
||||
// published data = only what's actually published, and IsDraft has to be false
|
||||
["fr-FR"] = new CultureVariation { Name = "name-fr1", IsDraft = false, Date = new DateTime(2018, 01, 01, 01, 00, 00) },
|
||||
["en-UK"] = new CultureVariation { Name = "name-uk1", IsDraft = false, Date = new DateTime(2018, 01, 02, 01, 00, 00) },
|
||||
["de-DE"] = new CultureVariation { Name = "name-de1", IsDraft = false, Date = new DateTime(2018, 01, 02, 01, 00, 00) }
|
||||
})
|
||||
.Build();
|
||||
|
||||
var kit = ContentNodeKitBuilder.CreateWithContent(
|
||||
2,
|
||||
1, "-1,1", 0,
|
||||
draftData: draftData,
|
||||
publishedData: publishedData);
|
||||
|
||||
return kit;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Verifies_Variant_Data()
|
||||
{
|
||||
// this test implements a full standalone NuCache (based upon a test IDataSource, does not
|
||||
// use any local db files, does not rely on any database) - and tests variations
|
||||
|
||||
// get a snapshot, get a published content
|
||||
IPublishedSnapshot snapshot = GetPublishedSnapshot();
|
||||
IPublishedContent publishedContent = snapshot.Content.GetById(1);
|
||||
|
||||
Assert.IsNotNull(publishedContent);
|
||||
Assert.AreEqual("val1", publishedContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop"));
|
||||
Assert.AreEqual("val-fr1", publishedContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop", "fr-FR"));
|
||||
Assert.AreEqual("val-uk1", publishedContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop", "en-UK"));
|
||||
|
||||
Assert.IsNull(publishedContent.Name(VariationContextAccessor)); // no invariant name for varying content
|
||||
Assert.AreEqual("name-fr1", publishedContent.Name(VariationContextAccessor, "fr-FR"));
|
||||
Assert.AreEqual("name-uk1", publishedContent.Name(VariationContextAccessor, "en-UK"));
|
||||
|
||||
var draftContent = snapshot.Content.GetById(true, 1);
|
||||
Assert.AreEqual("val2", draftContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop"));
|
||||
Assert.AreEqual("val-fr2", draftContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop", "fr-FR"));
|
||||
Assert.AreEqual("val-uk2", draftContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop", "en-UK"));
|
||||
|
||||
Assert.IsNull(draftContent.Name(VariationContextAccessor)); // no invariant name for varying content
|
||||
Assert.AreEqual("name-fr2", draftContent.Name(VariationContextAccessor, "fr-FR"));
|
||||
Assert.AreEqual("name-uk2", draftContent.Name(VariationContextAccessor, "en-UK"));
|
||||
|
||||
// now french is default
|
||||
VariationContextAccessor.VariationContext = new VariationContext("fr-FR");
|
||||
Assert.AreEqual("val-fr1", publishedContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop"));
|
||||
Assert.AreEqual("name-fr1", publishedContent.Name(VariationContextAccessor));
|
||||
Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.CultureDate(VariationContextAccessor));
|
||||
|
||||
// now uk is default
|
||||
VariationContextAccessor.VariationContext = new VariationContext("en-UK");
|
||||
Assert.AreEqual("val-uk1", publishedContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop"));
|
||||
Assert.AreEqual("name-uk1", publishedContent.Name(VariationContextAccessor));
|
||||
Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.CultureDate(VariationContextAccessor));
|
||||
|
||||
// invariant needs to be retrieved explicitly, when it's not default
|
||||
Assert.AreEqual("val1", publishedContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop", culture: ""));
|
||||
|
||||
// but,
|
||||
// if the content type / property type does not vary, then it's all invariant again
|
||||
// modify the content type and property type, notify the snapshot service
|
||||
_contentType.Variations = ContentVariation.Nothing;
|
||||
_propertyType.Variations = ContentVariation.Nothing;
|
||||
SnapshotService.Notify(new[] { new ContentTypeCacheRefresher.JsonPayload("IContentType", publishedContent.ContentType.Id, ContentTypeChangeTypes.RefreshMain) });
|
||||
|
||||
// get a new snapshot (nothing changed in the old one), get the published content again
|
||||
var anotherSnapshot = SnapshotService.CreatePublishedSnapshot(previewToken: null);
|
||||
var againContent = anotherSnapshot.Content.GetById(1);
|
||||
|
||||
Assert.AreEqual(ContentVariation.Nothing, againContent.ContentType.Variations);
|
||||
Assert.AreEqual(ContentVariation.Nothing, againContent.ContentType.GetPropertyType("prop").Variations);
|
||||
|
||||
// now, "no culture" means "invariant"
|
||||
Assert.AreEqual("It Works1!", againContent.Name(VariationContextAccessor));
|
||||
Assert.AreEqual("val1", againContent.Value<string>(Mock.Of<IPublishedValueFallback>(), "prop"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Verifies_Published_And_Draft_Content()
|
||||
{
|
||||
// get the published published content
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
var c1 = snapshot.Content.GetById(1);
|
||||
|
||||
// published content = nothing is draft here
|
||||
Assert.IsFalse(c1.IsDraft("fr-FR"));
|
||||
Assert.IsFalse(c1.IsDraft("en-UK"));
|
||||
Assert.IsFalse(c1.IsDraft("dk-DA"));
|
||||
Assert.IsFalse(c1.IsDraft("de-DE"));
|
||||
|
||||
// and only those with published name, are published
|
||||
Assert.IsTrue(c1.IsPublished("fr-FR"));
|
||||
Assert.IsTrue(c1.IsPublished("en-UK"));
|
||||
Assert.IsFalse(c1.IsDraft("dk-DA"));
|
||||
Assert.IsTrue(c1.IsPublished("de-DE"));
|
||||
|
||||
// get the draft published content
|
||||
var c2 = snapshot.Content.GetById(true, 1);
|
||||
|
||||
// draft content = we have drafts
|
||||
Assert.IsTrue(c2.IsDraft("fr-FR"));
|
||||
Assert.IsTrue(c2.IsDraft("en-UK"));
|
||||
Assert.IsTrue(c2.IsDraft("dk-DA"));
|
||||
Assert.IsFalse(c2.IsDraft("de-DE")); // except for the one that does not
|
||||
|
||||
// and only those with published name, are published
|
||||
Assert.IsTrue(c2.IsPublished("fr-FR"));
|
||||
Assert.IsTrue(c2.IsPublished("en-UK"));
|
||||
Assert.IsFalse(c2.IsPublished("dk-DA"));
|
||||
Assert.IsTrue(c2.IsPublished("de-DE"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.PublishedCache;
|
||||
using Umbraco.Cms.Tests.Common.Published;
|
||||
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.PublishedCache
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class RootNodeTests : PublishedSnapshotServiceTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
|
||||
string xml = PublishedContentXml.TestWithDatabaseXml(1234);
|
||||
|
||||
IEnumerable<ContentNodeKit> kits = PublishedContentXmlAdapter.GetContentNodeKits(
|
||||
xml,
|
||||
TestHelper.ShortStringHelper,
|
||||
out ContentType[] contentTypes,
|
||||
out DataType[] dataTypes).ToList();
|
||||
|
||||
InitializedCache(kits, contentTypes, dataTypes);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PublishedContentHasNoRootNode()
|
||||
{
|
||||
var snapshot = GetPublishedSnapshot();
|
||||
|
||||
// there is no content node with ID -1
|
||||
var content = snapshot.Content.GetById(-1);
|
||||
Assert.IsNull(content);
|
||||
|
||||
// content at root has null parent
|
||||
content = snapshot.Content.GetById(1046);
|
||||
Assert.IsNotNull(content);
|
||||
Assert.AreEqual(1, content.Level);
|
||||
Assert.IsNull(content.Parent);
|
||||
|
||||
// non-existing content is null
|
||||
content = snapshot.Content.GetById(666);
|
||||
Assert.IsNull(content);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user