Olá pessoal, tudo bem? Sejam todos muito bem-vindos a mais uma aula. E nesta aula a gente vai finalizar o Interface Adapter da parte de Event. Espero que até o final da aula a gente corrija todos os testes unitários. Quer dizer, os de unidade estão passando, agora os integrados, que dependem do framework, que não estão passando, porque a gente precisa de fato fazer alguns ajustes ali na persistência do evento. Então, bora lá. Vamos ver como é que está o caso de uso aqui. Beleza, já está trazendo os repositórios, tudo mais. Agora, então, a gente tem que fazer justamente aquilo que a gente estava fazendo. Então a gente já tem o nosso JPA evento, eu vou copiar o do ticket aqui e vou colocar event. Beleza, esse cara aqui implementa event repository, tudo que tiver aqui um ticket eu vou aproveitar para mudar para event e tudo que tiver em minúsculo também vou aproveitar para mudar para event beleza aproveitar para colocar o import correto aqui event id, import correto aqui também é claro a gente ainda não tem algumas coisas então a gente vai construir eles temos o nosso event entity aqui é tem o atributo id, que isso aqui já não é mais generated value, agora ele vai ser um id fixo, ele também é um uuid, a própria implementação, a própria classe da JVM, string name, date, total spots, manage one, tem um relacionamento com partner, aqui a gente vai tirar esse relacionamento e vamos deixar apenas um partner id, e aqui ele se relaciona com ticket, só que na verdade a gente não vai fazer esse relacionamento com ticket também, o que a gente vai fazer é criar uma entidade chamada event ticket só para fazer um relacionamento de eventos com tickets. Basicamente é uma tabela pivô entre as duas. Nessa tabela o que ele vai ter? Vamos só ver como é que está o evento porque vai ser muito parecido com aquilo, né? Então, ó, vamos ver o evento, event ticket, ticket ID, event ID, customer ID e ordering. Então, vamos lá, o que a gente tem que fazer? Cadê? Event ticket. Beleza, então vai ter aqui o ticket ID, customer ID, event id e por último um inch ordering show de bola vamos verificar isso aqui deixa eu ver como é que tá o ticket aqui. O ticket ele tem esses relacionamentos customer event ok, basicamente fica duplicado, vai ficar duplicado esse cara, mas só para facilitar o evento não tem como fugir, o evento vai ficar duplicado mesmo justamente por ser uma tabela pivô. No ticket como aqui também tem o event id, poderia não ter poderia não ter, poderia usar só a tabela pivô para ter esse campo o customer id tem que ter mas, de certa forma, também não tem problema está relacionado assim tá bom então vamos lá deixou aar isso aqui ticket ordering isso aqui vala, aqui a gente vai superar basicamente um event ah, faltou aqui o relacionamento também, né? Então a gente tem o event entity event, que é basicamente um many to one com o fat type de lazy ok então a gente vai receber aqui um event entity event e um final event ticket ticket. ev.ticketid e ev.customerid. E aqui é basicamente esse event id não vamos ter aqui assim, vamos deletar, é basicamente costume ordem eo evento aqui um relacionamento direto é esse cara a gente na verdade o evento em que event e aí diz ponto evento igual a event beleza o órg mover o order para cima só para ficar compliance aqui cadê o customer id vamos colocar aqui como ev.ordering e event beleza show de bola agora da mesma forma como a gente criou esse factory method pra ajudar na criação, na construção, a gente vai ter também um reverso pra instanciar o event ticket event ticket a gente tem basicamente ticket ID event ID, customer e ordering vamos lá começa com na verdade a ticket, evento e customer mesma coisa como já tá ali então ticket, event e customer disso, ticket id, .toString event id na verdade a gente precisa pegar o event.getid.toString customerId e ordering Fechou Deixa eu ver se o construtor... Ah, ele está como protected Verdade O que a gente pode fazer aqui duas coisas ou mover para o público ou mover para ou criar um factory method basicamente que vai fazer essa validação aqui pra gente é um factory method que vai chamar esse construtor pra gente no final das contas não faria muita diferença né então por isso podemos mover para público a gente também pode fazer igual fizemos aqui ó a gente também pode fazer com esse a não mentira não poderia fazer justamente porque ele já é final né então é a ordenação não muda então a validação aqui no construtor faz total sentido. Agora, o que a gente vai fazer? Vamos corrigir esse event ticket aqui, porque agora tem um monte de getters e setters que não estão sendo utilizados. Então, insert getter e setter. e até de setor e que a gente vai fazer aqui que deve fazer corrigir essa parte desse nosso relacionamento aqui então a gente não vai ter mais fica gente vai ter event ticket entity. Ele tem um casquete, ele é mapeado pelo event, então eu tenho um evento para muitos event tickets, e o que a gente deve colocar aqui, por exemplo, é um fetch type lazy, porque ele vem, fetch type lazy não, fetch type eager, justamente porque pelo fato de a gente estar obtendo, justamente porque pelo fato de a gente estar obtendo e sempre obtendo um evento através do nosso agregado de evento e através do nosso repository, no nosso agregado ele sempre demanda que esses caras, que os tickets sejam carregados. Então sempre precisa vir populado e é por isso que nesse cenário faz sentido colocar um eager aqui, porque a gente sabe que a gente vai sempre utilizar mesmo. Então, dessa forma, a gente já busca todos os tickets e evita quaisquer n plus one queries. Então, beleza. Temos aqui um um evento que é de vazio é o que a gente pode até chamar o disso pra inicializar a que a gente vai ter de ponto aí de vamos mudar para o aí não é mais isso nem me deite total spots e aqui a gente vai ter basicamente partner o uai de partenar a gente não vai ter tica daqui porque o tíquete vai ser utilizado só depois que que que só depois que que is.partnerid is.partnerid igual a partnerid beleza vamos limpar esses getters e setters aqui e a gente coloca a gente insere de novo getters getters e setters aqui a gente coloca a gente sabe de novo de ter setas ok e aí o que a gente tem que fazer também o mesmo site meta que espete que event and off event evento event, event, beleza. O que a gente vai fazer aqui então? A gente vai primeiro instanciar entity igual a new eventEntity passando event.getEventId.value .value .uid .fromString aí vamos precisar agora event.name event.date event.totalSpots e event.partnerId opa event.partner .partner partner id o id.fromstring .value beleza ah tá, o name tá encapsulado então .value agora com esse end a gente pode chamar é event.alltickets.forEach ticket, entry.addTicket e a gente passa o ticket, e quem quer esse addTicket a gente vai criar aqui agora que é basicamente diz ponto ticket ponto add event ticket change ponto off diz e ticket e aí pode ser um método reference e aí a gente faz o return no event no entity beleza agora a lógica inversa é a mesma coisa quer dizer, parecido public.event to event return new ah tá, agora é o seguinte a gente pode utilizar o new event ou utilizar uma técnica para facilitar um pouco que é event.restore e aí passar os valores aqui então, dis.id .toString, .name, .date, .totalspot, .partnerId e por último diz ponto é a gente vai chamar basicamente event ticket.toSets show de bola, e esse restore a gente vai precisar criar porque ele não existe, ai tem um detalhe aqui, repository esse cara aqui na verdade é uma string e aí vai ser instanciado o event eventid.withString que na real é id beleza vamos só colocar os os painéis aqui né esse aqui ó é a total os potes vamos quebrar a linha que ficou uma ficou bem grande esse cara que é o partner id e esse aqui são os tickets partner e ele é string beleza então agora sim name, date, total spots, partner id e tickets cadê o partner id a gente vai precisar criar um construtor que recebe ticket Final set event tickets. Basicamente. Como ele já inicializa ali, a gente pode passar para lá. Ou não, né? Mas vamos fazer o seguinte. Vamos passar para lá os tickets a gente vai ter aqui então final set event tickets diferente de nulo, usa os tickets, se não cria com capacete zero. Beleza. Como esse construtor também ficou bastante grande, vamos começar a quebrar linhas aqui, sem economizar linhas. Beleza, agora aqui a gente vai new event, a gente pode passar new hash set, ou então nula, né, porque a gente já trata nulo lá, beleza? vamos mudar para partner id aqui na verdade ele demanda um partner id claro partner id with agora sim beleza então já estamos com restore esse aqui é o format date time format isolocal date e esse aqui to string né porque ele é um uid deixa eu só ver se o isolocal date deixa eu checar o isolocal date de novo cadê isolocal date beleza tá certo vamos lá então agora a gente já tem o nosso evento vale event jpa a gente tem que mudar aqui pra o id não é mais long e esse aqui é event of id create papapá beleza aparentemente está correto vamos rodar os testes para ver como é que ficou to event ticket event.id beleza long.partylong event subscribe create result tá esse cara ele é uma string findById agora ele não é mais long.partLong é o id.from all tickets beleza vamos rodar os testes ainda tem algum problema ah, talvez faltou table tickets contém fisco nem 20 de refeição de pós-produtos também o papo era aí e aí o que deixa eu ver esse cara aqui gente a event tickets acho que agora vai mudar de novo testes e a tá aí faltou o nome por um nome nome melhor aqui né porque se não vai ficar com o entity aqui a mesma coisa vamos ver aqui aqui também, todos esses eu gosto de colocar o nome porque se você não colocar o nome vai ficar como customer entity e ai vai ficar até estranho na query a select all ou select alguma coisa for um customer entity quando você tem quando você faz uma query manual do hybrid então por isso a gente pode substituir para partner sem o sufixo entity beleza vamos ver agora o que ele deu de erro ah ta falta a gente arrumar os nossos queridos use cases né porque tá tudo nulo aqui então a gente já estamos utilizando o customer tem mais algum lugar que tem customer customer customer, customer, customer, event, event, event, partner, então temos o partner, temos o partner, partner aqui também, e aí depois por último o ticket, beleza, rodando todos os testeses E agora a gente pode tirar esses to do's Agora não temos Mais esses to do's Ficou de bola Vamos ver Id, for de clasma, beleza A gente precisa setar o id Antes de solicitar O save, né, é porque de fato Mudou, então o create customer Ele tá trazendo o repository aqui direto vamos fazer o seguinte, vamos mudar para repository do nosso repository lá da camada de application inclusive ele vai precisar de um delete all aqui, justamente para facilitar os testes. Precisávamos fazer isso? Poderíamos só utilizar o JPA repositório como a gente estava fazendo ali? Sim, só que eu vejo uma desvantagem que de repente se você fizer isso, Eu vejo uma desvantagem que, de repente, se você fizer isso, pode ser que abra margem para criar algum tipo de inconsistência dos dados. Porque a sua aplicação começa a persistir e manipular através dos agregados que passam para os repositórios. Se você, no teste, só persistir através dos repositórios direto, pode ser que alguma coisa falte, alguma validação, alguma informação falte na hora de você instanciar direto uma entity, por exemplo, e com isso você cria alguma inconsistência só nos testes, que não é uma inconsistência que reflete a aplicação real, e aí você começa a adicionar outras coisas, outras validações, só para lidar com essas inconsistências que foram criadas por conta de um teste que nunca vai reproduzir o que é real, né, então é por isso que eu gosto de trabalhar com o repository aqui que é como a camada de aplicação e os meus cases trabalham, certo? Então vamos lá after it, na verdade ao invés de usar o after it, vamos usar o before it em tudo, porque assim a gente garante que vai estar limpo o que eu preciso, porque se eventualmente vir algum outro teste que deixou o banco sujo, esse meu teste aqui pode quebrar. CustomerEntity agora não é mais CustomerEntity e agora é Createe então a gente vai criar aqui um customer ponto new customer nem me cpf e mail deixa só ver se mesmo em cpf e mail beleza e ele vai tornar um customer ok vamos ver o que mais que está quebrando ah, claro, implementar o delete all em todos esses que a gente acionou, né delete all cadê, event delete all diz ponto event delete all deixa eu aproveitar e renomear Dis.event.deleteAll Deixa eu aproveitar e renomear isso aqui Ficou ruim EventRepository, beleza O partner também precisa Dis.partner.deleteAll Aqui a mesma coisa Dis.ticket.deleteAll aqui a mesma coisa e lá nas implementações em memoria também vão precisar ter, então vamos lá deleteAll que é basicamente isso aqui só que ao invés de chamar um put, a gente vai chamar um clear events chamar um clima de um ponto clima e memória de ponto par a como tem mais o mesmo esquema aqui. Copiar e colar. Até o final. D. Clear. Beleza. E por último, o ticket. Ticket. Clear. Fechou. Vamos rodar os testes de novo. Opa, estamos quase. Em vale de... Ah, em vale de Inválido de CPF. Beleza. A gente adicionou as máscaras. E não modificamos alguns testes. Então vamos lá. Deixa eu ver se tem mais aqui. 1, 2, 3. 1, 2, 3. 1, 2, 3. ID. Create event. Ah, está. O mesmo problema aqui, então vamos lá, vamos trazer o partner jpa, o partner repository e o event repository, before each, setup, e aqui embaixo vai ser basicamente, e aqui embaixo vai ser basicamente retornar partner create partner ponto new partner que é name cnpj e mail e vamos ver como é que está o cnpj aqui também vai precisar mudar a parte da id então cnpj 12123 barra beleza vamos dar o teste novo pra ver aonde mais continua quebrando pra gente ajustar rapidinho né invalide for expected cpf, tem alguns lugares aqui, 123.23.23 invalide value for partner id create create partner create partner name tá, calma aí, a gente já a gente já verifica o que é esse aí vamos ver os outros unrecognize invalid deve obter um cliente por id ah ID, acho que a gente tem que resolver aqui os cps, 1, 2, 3, traço, 1, 2, 3, traço, o e-mail já está certo, tenta criar um, um, dois, três, um, dois, três, um, dois, três, traço. Não deve cadastrar um cliente com e-mail duplicado, deve obter o cliente por CPF, não deve cadastrar com CPF duplicado, deve cadastrar um cliente, beleza. Test create. A gente precisa de ID, né? Porque a gente está... Vamos atualizar esse cara aqui também. Vamos trazer os repositories e não o JPA direto. Import. Import. Import. Import. Customer repository. o corte forte o importe custom repository cliente customer new customer de gente ativa aí aqui e o john do basicamente a customer e partner o cliente também partner, create também, partner, new partner, estilo id, cnpj e mail, show de bola, aqui vai ser id, ou melhor, partner id, ah e nem é .valid .valid aqui John Doe customer id .valid event of id event id with Event of ID. Event ID with getAllTickets. Beleza, vamos mudar os testes de novo. Trabalho de formiguinha, né? Mas pelo menos a gente já tem muito mais confiança justamente por haver testes. Esse aqui é o seguinte, não é toString, é value, beleza, vamos ver os outros. unrecognizedCustomer, customer already exists, está retornando uma mensagem de erro aqui, vamos ver, after-each vamos trocar por before-each setup event-control-cpf invade-cpf after-each vamos trocar por before-each também setup cpf, after it, vamos tocar por before it também, setup na verdade como assim, como a gente já tem aqui fazer o seguinte beleza, e no partner aqui também a mesma coisa Default it Setup E aqui é Partner repository Vamos ver o que está quebrando Beleza, vamos mudar o set novamente Ó Passou na trave, hein a id ele espera um número então agora é um string e aqui a mesma coisa aqui a mesma coisa e esse aqui inválido deve criar um evento aqui em vale deve criar um evento em várias de cpf a claro em um bar né 4 16 contra alguma coisa beleza agora aqui vamos ver, invalid invalid cpf a lá a gente precisa ajustar também 123 123 barra mil contra traço beleza, vamos rodar então barra, mil, contra, traço e beleza. Vamos rodar então todos os testes. Será que agora vai? Quase de novo, hein? Vamos lá, vamos ver o que ele está reclamando ainda. Ah, tá. IsString e aqui IsString IsString e aqui isString isString isString isString beleza acho que é só isso vamos ver partner.alway.exists 201 created, ah pera aí, aqui tem um problema de CNPJ, milcontra, traço. Beleza, vou mudar esse teste de novo show de bola, agora eu tenho certeza que todos estão passando, vou mudar novamente todos os testes aqui dentro do packet desagonal excelente, então todos os nossos testes estão passando refatoramos toda a layer de entrada dos inbound adapters dos nossos casos de uso, dos nossos domínios das entidades e por fim dos outbound adapters, que são os secondary actors agora quase 100% compliance com o que a gente tem de hexagonal. Todos os testes bonitos passantes. E aí, na próxima aula, a gente pode até fazer um teste de regressão, para ver como é que estamos a aplicação rodando. Então, é isso. Espero que vocês tenham gostado. Vejo vocês na próxima aula.