### Question:
FreemarkerInstruction extends FileInstruction { @Override public InstructionStatus process(final PluginContext context, final InstructionStatus previousStatus) { log.debug("executing Freemarker Instruction {}", this); processPlaceholders(context.getPlaceholderData()); if (!valid()) { eventBus.post(new MessageEvent("Invalid instruction descriptor: " + toString())); eventBus.post(new InstructionEvent(this)); return InstructionStatus.FAILED; } if (repoBased && !Strings.isNullOrEmpty(repositoryTarget) && !Strings.isNullOrEmpty(templateName)) { log.debug("Using repository stored freemarker templates"); final Session session = context.createSession(); InputStream stream = null; try { stream = extractStream(); if (stream == null) { log.error("Stream was null for source: {}", getSource()); return InstructionStatus.FAILED; } final String absPath = repositoryTarget + '/' + templateName; if (session.nodeExists(absPath)) { log.debug("Node already exists {}", absPath); return InstructionStatus.SKIPPED; } final Node templatesRootNode = session.getNode(repositoryTarget); log.debug("Adding freemarker template: {}", templateName); final Node templateNode = templatesRootNode.addNode(templateName, "hst:template"); final String content = GlobalUtils.readStreamAsText(stream); final String replacedData = TemplateUtils.replaceTemplateData(content, context.getPlaceholderData()); templateNode.setProperty("hst:script", replacedData); session.save(); return InstructionStatus.SUCCESS; } catch (RepositoryException e) { log.error("Error writing freemarker template", e); } catch (FileNotFoundException e) { log.error("Error extracting stream", e); } finally { IOUtils.closeQuietly(stream); GlobalUtils.cleanupSession(session); } return InstructionStatus.SUCCESS; }else { return super.process(context, previousStatus); } }  @Override InstructionStatus process(final PluginContext context, final InstructionStatus previousStatus); void setRepositoryTarget(final String repositoryTarget); String getTemplateName(); String getRepositoryTarget(); boolean isRepoBased(); @Override void processPlaceholders(final Map<String, Object> data); @Override String toString(); static final ImmutableSet<String> DEFAULT_HST_TEMPLATES; }### Answer:
@Test public void testProcess() throws Exception { super.createHstRootConfig(); instruction.setAction("copy"); instruction.setSource(SOURCE); instruction.setTarget("{{freemarkerRoot}}/{{namespace}}/homepage-main-content.ftl"); log.info("instruction {}", instruction); assertTrue(instruction.valid()); final PluginContext context = getContext(); context.addPlaceholderData(EssentialConst.PROP_TEMPLATE_NAME, EssentialConst.TEMPLATE_FREEMARKER); context.addPlaceholderData(EssentialConst.TEMPLATE_PARAM_FILE_BASED, false); context.addPlaceholderData(EssentialConst.TEMPLATE_PARAM_REPOSITORY_BASED, true); assertTrue(instruction.valid()); final String projectNamespace = (String) context.getPlaceholderData().get(EssentialConst.PLACEHOLDER_NAMESPACE); log.info("projectNamespace {}", projectNamespace); instruction.process(context, InstructionStatus.SUCCESS); assertEquals("/hst:hst/hst:configurations/" + projectNamespace + "/hst:templates", instruction.getRepositoryTarget()); assertEquals("homepage-main-content.ftl", instruction.getTemplateName()); instruction.process(context, InstructionStatus.SKIPPED); }